Skip to content

Testing Framework for CMake

License

Notifications You must be signed in to change notification settings

mrowrpurr/CSpec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This is a fun, silly prototype.

But I'm actually using it to fully test-drive a CMake project.

Check back when 0.2 is available:

  • supports easy generation of CMake projects and building their targets
  • includes various expect(...)-style assertions

Coming soon!


CSpec

Testing Framework for CMake

CSpec

What?

CMake scripts can be pretty complex.

I wanted to be able to test-drive my CMake scripts, so I wrote this.

It's less than 80 lines of code, but provides a lovely testing interface.

Install

CSpec is available via vcpkg (from mrowrpurr's vcpkg repo)

Get from vcpkg

  1. Add cspec as a dependency to your vcpkg.json
  2. Add mrowrpurr's vcpkg registry to your vcpkg-configuration.json

vcpkg.json

View Content
{
    "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
    "name": "hello-world",
    "version-string": "0.0.1",
    "dependencies": [
        "cspec"
    ]
}

vcpkg-configuration.json

View Content
{
  "default-registry": {
    "kind": "git",
    "repository": "https://github.com/microsoft/vcpkg.git",
    "baseline": "cc288af760054fa489574bd8e22d05aa8fa01e5c"
  },
  "registries": [
    {
      "kind": "git",
      "repository": "https://github.com/mrowrpurr/vcpkg-repo.git",
      "baseline": "fbc7feae4c02684332fe6c9fec8320bef34729b3",
      "packages": [
        "cspec"
      ]
    }
  ]
}

Add to CMakeLists.txt

Once you've added cspec as a vcpkg dependency, load the package in CMake:

find_package(CSpec CONFIG REQUIRED)

Write Tests

Writing tests is easy, just make a [whatever].cmake file.

In your CMakeLists.txt, specify the file:

# You can leave off the .cmake extension
add_cspec_suite(MySpecs)

A CMake target named MySpecs will be available. Build it to run the tests.

MySpecs.cmake

function(setup)
    # This runs before each test function is run.
    # Note: tests are run in SEPARATE processes and do not share variables.
    do_some_setup()
    set(SomeSharedVariable "Shared Value" PARENT_SCOPE)
endfunction()

function(teardown)
    # This runs after each test function is run (even if the test fails).
    do_some_cleanup()
endfunction()

function(test_this_should_pass)
    # Because this function starts with "test_"
    # it will be automatically run!
    
    # Also, setup() runs before this so we have access to shared variables:
    message("I got a value from setup() - ${SomeSharedVariable}")
endfunction()

function(test_this_should_fail)
    # Anything which will cause the program to fail
    # will cause the test to fail:
    message(SEND_ERROR "This message will show up in test output")
endfunction()

Example Output

[build]   [FAIL] test_should_fail
[build]       CMake Error at C:/Users/mrowr/AppData/Local/Temp/cspec/ec308d4b3c337173b30c142dfd5ff1e7bf9dbe82/HelloCSpec.cmake:16 (message):
[build]         This should be a failure message!
[build]       Call Stack (most recent call first):
[build]         C:/Code/mrowrpurr/CSpec/CSpec.cmake:52:EVAL:1 (test_should_fail)
[build]         C:/Code/mrowrpurr/CSpec/CSpec.cmake:52 (cmake_language)
[build]         C:/Users/mrowr/AppData/Local/Temp/cspec/ec308d4b3c337173b30c142dfd5ff1e7bf9dbe82/HelloCSpec.cmake:19 (__cpec_test_suite_end)
[build]   [PASS] test_should_pass

Assertions

At this time, there are no custom assertions written.

Simply message(SEND_ERROR "something") or message(FATAL_ERROR "something) to fail a test.