• Stars
    star
    106
  • Rank 325,871 (Top 7 %)
  • Language
    C
  • License
    GNU General Publi...
  • Created over 10 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Small BDD framework for C/C++

CSpec [https://mumuki.github.io/cspec/]

Small behavior driven development (BDD) framework for C.

Show me an example, please!

#include <stdio.h>
#include <stdbool.h>
#include <cspecs/cspec.h>

context (example) {

    describe("Hello world") {

        it("true should be true") {
            should_bool(true) be equal to(true);
        } end

        it("true shouldn't be false") {
            should_bool(true) not be equal to(false);
        } end

        it("this test will fail because 10 is not equal to 11") {
            should_int(10) be equal to(11);
        } end

        skip("this test will fail because \"Hello\" is not \"Bye\"") {
            should_string("Hello") be equal to("Bye");
        } end

    } end

}
  • Compile: gcc cspecExample.c -o cspecExample -lcspecs
  • Execute: ./cspecExample

  Hello world
    ✔ true should be true
    ✔ true shouldn't be false
    1) this test will fail because 10 is not equal to 11
    â€ĸ this test will fail because "Hello" is not "Bye"


  Summary

    1) Hello world - this test will fail because 10 is not equal to 11
      - Expected <11> but was <10> [./cspecExample.c:18]

  2 success
  1 failure
  1 pending

Let's get started!

How do I install it?

  1. git clone https://github.com/mumuki/cspec.git
  2. cd cspec
  3. make install

Now, what should I do?

  • Write your C code
  • Write your specs
  • Compile with the -lshould`` option. For example: gcc -lcspecs cspecExample.c -o cspecExample
  • Run it on the console: ./cspecExample

What does cspec offer me?

It offers you a set of operations - like RSpec, Mocha or Jasmine - that allows you to make oriented behavior (unit and integration code) tests.

How do I use the framework?

context

Each behaviour to test must be declared within a context. The syntax to define a context is shown below:

context(<identifier>) {
    /* You're inside the context */
}

Inside a context, you can write functions and call them in your tests, you can also include files (.h), define macros and write scenarios using describe.

describe

Each scenario is written inside a describe, declared in this way:

describe("Brief description of the scenario") {
    /* Here goes the code */
} end

Again, inside a describe you can write functions and call them in your tests, include files (.h), define macros and write the tests using it.

it

Each it represents a test.

it("Brief description of the test") {
    /* Here goes the test code, along with the assertions */
} end

Inside it, you have to write the assertions about the behaviour you want to test. In order to do that cspec has a set of basic operations to do that, the should statements.

should

Each should is an assertion, that expects 2 values. The first is the actual value and the second, the expected one.

should_bool(<actual_boolean>) be equal to(<expected_boolean>);
should_bool(<actual_boolean>) not be equal to(<unexpected_boolean>);

should_char(<caracter_actual>) be equal to(<caracter_esperado>);
should_char(<caracter_actual>) not be equal to(<caracter_no_esperado>);

should_short(<actual_number>) be equal to(<expected_number>);
should_short(<actual_number>) not be equal to(<unexpected_number>);

should_int(<actual_number>) be equal to(<expected_number>);
should_int(<actual_number>) not be equal to(<unexpected_number>);

should_long(<actual_number>) be equal to(<expected_number>);
should_long(<actual_number>) not be equal to(<unexpected_number>);

should_float(<actual_float>) be equal to(<expected_float>);
should_float(<actual_float>) not be equal to(<unexpected_float>);

should_double(<decimal_actual>) be equal to(<decimal_esperado>);
should_double(<decimal_actual>) not be equal to(<decimal_no_esperado>);

should_ptr(<actual_pointer>) be equal to(<expected_pointer>);
should_ptr(<actual_pointer>) not be equal to(<unexpected_pointer>);

should_string(<actual_word>) be equal to(<expected_word>);
should_string(<actual_word>) not be equal to(<unexpected_word>);

Also, cspec offers syntactic sugar for some of the assertions, like the following examples:

should_bool(<actual_boolean>) be truthy;
should_bool(<actual_boolean>) not be truthy;

should_bool(<actual_boolean>) be falsey;
should_bool(<actual_boolean>) not be falsey;

should_ptr(<actual_pointer>) be null;
should_ptr(<actual_pointer>) not be null;

Hooks - before y after

Sometimes the scenarios, initial configurations, or deallocation of the variables get repeated between tests. In order to handle that, inside each describe, you can add a block code to execute before and after each test (it).

before

before {
    /* Code to execute before each test */
} end

after

after {
    /* Code to execute after each test */
} end

Note: As stated before, the context and the describe are executed secuentially, that's why it's very important to remember that the before and after must be declared in the beggining of the describe scenario, even before the first test.

Now let's see a complete example, with the execution flow

#include <stdio.h>
#include <stdlib.h>
#include <cspecs/cspec.h>

context (complete_example) {

    describe("Describe 1") {

        int *a = NULL,
             b;

        before {
            puts("before 1");
            a = malloc(sizeof(int));
            *a = 10;
            b = 20;
        } end

        after {
            puts("after 1");
            free(a);
            a = NULL;
        } end

        it("*a should be 10 and b should be 20") {
            should_int(*a) be equal to(10);
            should_int(b) be equal to(20);
        } end

        describe("Describe 2") {

            before {
                puts("before 2");
                *a = 30;
                b = 15;
            } end

            after {
                puts("after 2");
                free(a);
                a = NULL;
            } end

            it("*a should be 30 and b should be 15") {
                should_int(*a) be equal to(30);
                should_int(b) be equal to(15);
            } end

            describe("Describe 3") {

                before {
                    puts("before 3");
                    b = 150;
                } end

                after {
                    puts("after 3");
                    free(a);
                    a = NULL;
                } end

                it("*a should be 30 and b should be 150") {
                    should_int(*a) be equal to(30);
                    should_int(b) be equal to(150);
                } end

            } end

        } end

        describe("Describe 4") {

            it("*a should be 10 and b should be 20") {
                should_int(*a) be equal to(10);
                should_int(b) be equal to(20);
            } end

        } end

    } end

}

Once the code has been compiled and executed, it'll give us a report of all the tests like the following:


  Describe 1
before 1
    ✔ *a should be 10 and b should be 20
after 1
    Describe 2
before 1
before 2
      ✔ *a should be 30 and b should be 15
after 2
after 1
      Describe 3
before 1
before 2
before 3
        ✔ *a should be 30 and b should be 150
after 3
after 2
after 1
    Describe 4
before 1
      ✔ *a should be 10 and b should be 20
after 1


  Summary

  4 success

Are you using Eclipse IDE and it's showing errors all over the project?

You need to add cspec to the project dependencies. In order to do that, follow these steps...

  1. Right click on the project => Properties
  2. In the right panel go to C/C++ Build => Settings => Tool Settings => GCC C++ Linker => Libraries
  3. In the right pannel, above (Libraries (-l)), click on add and then write cspec
  4. Apply changes
  5. Recompile the project

License

This framework uses the GPLv3 as license. Fork it and contribute with the project!

Thanks!

More Repositories

1

mumuki-laboratory

đŸ”Ŧ Where students practice and receive automated and human feedback
Ruby
203
star
2

mulang

🎍 Universal, Multi Language, Multi Paradigm code analyzer
Haskell
124
star
3

mumuki-xgobstones-runner

Sinatra server for validating XGobstones programs within Mumuki
Ruby
5
star
4

mumukit

Micro Framework for quickly implementing Mumuki runners
Ruby
5
star
5

mumuki-bibliotheca-api

📚 Storage and formatting API for Mumuki content
Ruby
4
star
6

escualo.rb

**Deprecated** Provisioning tool for Mumuki Platform
Ruby
4
star
7

mumukit-auth

🔒 Ruby gem for handling user permissions within Mumuki
Ruby
4
star
8

mumuki-ruby-runner

💎 Sinatra server for running Rspec tests within Mumuki
Ruby
4
star
9

mumukit-bridge

⛩ī¸ Library for connecting to Mumuki runners
Ruby
4
star
10

mumuki-styles

Mumuki Styles
SCSS
4
star
11

mumuki-wollok-runner

Ruby
3
star
12

mumuki-cpp-runner

Ruby
3
star
13

mumuki-java-runner

☕ Sinatra server for validating Java programs within Mumuki
Ruby
3
star
14

mumuki.github.io

Spanish Technical Documentation for the Mumuki Platform
SCSS
3
star
15

mumuki-hspec-server

Snap server for running Haskell tests within Mumuki
Haskell
3
star
16

mumuki-prolog-runner

Sinatra server for running PLUnit tests within Mumuki
Ruby
3
star
17

mumuki-mocha-server

Node server for running mocha tests within Mumuki
JavaScript
3
star
18

dev-awesome

Handlebars
2
star
19

mumukit-inspection

👓 Minimal library for parsing Mumuki inspection language
Ruby
2
star
20

mumukit-core

Ruby
1
star
21

mumuki-metaprogramming-ruby-guide-1

Ruby
1
star
22

mumuki-platform

Documentation and issues for the Mumuki Platform.
1
star
23

mumuki-minitest-runner

Ruby
1
star
24

mumukit-nuntius

Ruby
1
star
25

mumukit-login

Omniauth-based login library for Mumuki Platform
Ruby
1
star
26

mulang-ruby

👓 Ruby Support for the Mulang code analyzer
Ruby
1
star
27

hspec-structured-formatter

Haskell
1
star
28

mumuki-gobstones-runner

🔴 Runner for validating Gobstones programs within Mumuki
Ruby
1
star
29

mumuki-guia-fundamentos-javascript-vectores

JavaScript
1
star
30

mumuki-guia-fundamentos-javascript-variables-y-procedimientos

JavaScript
1
star
31

stones-spec

Minimal test framework for Gobstones
1
star
32

mumuki-domain

💡 Mumuki's domain model
Ruby
1
star
33

mumuki-haskell-runner

Ruby
1
star
34

mumuki-classroom-api

API for tracking students' progress within Mumuki.
Ruby
1
star
35

mumuki-sqlite-runner

SQLite runner for Mumuki Project using Docker container
Ruby
1
star
36

mumuki-elixir-runner

Ruby
1
star