├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── README.md ├── lib.c ├── lib.h ├── makefile ├── run_coverage_test.sh └── test-library.c /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Install dependencies 18 | run: | 19 | sudo apt-get update 20 | sudo apt-get install -y gcc lcov libncurses5-dev 21 | 22 | - name: Build project 23 | run: | 24 | make 25 | 26 | - name: Run tests 27 | run: | 28 | ./test-library.out 29 | 30 | - name: Capture coverage info 31 | run: | 32 | lcov --directory . --capture --output-file coverage.info 33 | 34 | - name: Filter out system and test code 35 | run: | 36 | lcov --remove coverage.info 'tests/*' '/usr/*' 'test-library*' --output-file coverage.info 37 | 38 | - name: List coverage info 39 | run: | 40 | lcov --list coverage.info 41 | 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Embedded Target files 35 | *.lst 36 | *.sym 37 | *.asm 38 | *.rel 39 | *.s 40 | 41 | # code coverage files 42 | *.gcov 43 | *.gcda 44 | *.gcno 45 | 46 | dioci-example.out -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | install: 4 | - cd ${TRAVIS_BUILD_DIR} 5 | # Install LCOV from the package manager 6 | - sudo apt-get update 7 | - sudo apt-get install -y lcov 8 | 9 | # Install coveralls-lcov 10 | - gem install coveralls-lcov 11 | 12 | before_script: 13 | - cd ${TRAVIS_BUILD_DIR} 14 | - lcov --directory . --zerocounters 15 | 16 | compiler: 17 | - clang 18 | - gcc 19 | 20 | script: 21 | - cd ${TRAVIS_BUILD_DIR} 22 | - make && ./test-library.out 23 | 24 | after_success: 25 | - cd ${TRAVIS_BUILD_DIR} 26 | - lcov --directory . --capture --output-file coverage.info # capture coverage info 27 | - lcov --remove coverage.info 'tests/*' '/usr/*' 'test-library*' --output-file coverage.info # filter out system and test code 28 | - lcov --list coverage.info # debug before upload 29 | - coveralls-lcov coverage.info # for open source 30 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2016, M. A. Chatterjee 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://app.travis-ci.com/deftio/C-and-Cpp-Tests-with-CI-CD-Example.svg?token=Pc8RELtY2RwRuTT1tezA&branch=master)](https://app.travis-ci.com/deftio/C-and-Cpp-Tests-with-CI-CD-Example) 2 | [![Coverage Status](https://coveralls.io/repos/github/deftio/travis-ci-cpp-example/badge.svg?branch=master)](https://coveralls.io/github/deftio/travis-ci-cpp-example?branch=master) 3 | [![License](https://img.shields.io/badge/License-BSD%202--Clause-blue.svg)](https://opensource.org/licenses/BSD-2-Clause) 4 | [![Github Actions Ci](https://github.com/deftio/C-and-Cpp-Tests-with-CI-CD-Example/actions/workflows/ci.yml/badge.svg)](https://github.com/deftio/C-and-Cpp-Tests-with-CI-CD-Example/actions/workflows/ci.yml/badge.svg) 5 | 6 | # Simple Example for C/C++ Tests with Continuous Integration (CI) 7 | 8 | This repository demonstrates setting up a basic testing suite with GitHub badges for a C/C++ library. It covers the basics of setting up unit tests, coverage tests, and continuous integration using GitHub Actions or Travis-CI. The repository contains a simple library tested for coverage and integration. 9 | 10 | ## Motivation 11 | 12 | This project provides a small standalone example to show continuous integration tools and workflows for C (or C++) language testing without the overhead of a much larger project. 13 | 14 | ## Features 15 | 16 | The lib.h and lib.c files are examples of testing an embedded library. Many of the projects I work on are for embedded systems, so I wanted a way to get a build badge for these projects. This example abstracts how the CI process works without the complexities of a "real" project. 17 | 18 | ## How It Works 19 | 20 | This demo project includes a C library with a few demo functions in lib.h and lib.c. The code doesn't do much but serves as a simple abstraction of what is necessary to build a larger project. This repository provides an overview of testing and how to get build badges working on GitHub. 21 | 22 | ## Quick Overview of Testing 23 | 24 | Testing helps tell us if the software is working as intended. This means understanding what we want to test in to a few key areas. 25 | 26 | ### Common Testing Questions 27 | 28 | * Does it run as intended? 29 | * Does it have side effects when running? 30 | * Are resources tied up such as ports blocked, thread contention? 31 | * Are other programs or services affected unintentionally? 32 | * Are all possible execution paths tested? (coverage) 33 | * How much memory or resources are used? Is memory freed correctly / are their leaks? 34 | * Does it exit gracefully? 35 | * Is the performance good enough? 36 | * Is it reliable? 37 | 38 | These are just a few of questions that testing can answer. Each of these questions can take us on different paths to find the answer. A good start is with unit testing. 39 | 40 | ### Unit Testing 41 | 42 | Unit Testing involves writing small tests to ensure that a piece of code, typically a module or library, passes a set of tests to verify it runs as intended. The goal is to craft tests that cover all possible paths of execution in the code. 43 | 44 | Example function: 45 | 46 | ```c 47 | int add5ifGreaterThan2(int a) { 48 | int r; 49 | if (a > 2) 50 | r = a + 5; 51 | else 52 | r = a; 53 | return r; 54 | } 55 | ``` 56 | 57 | Test code: 58 | 59 | ```c 60 | ASSERT(add5ifGreaterThan2(1) == 1) // tests if (a <= 2) case 61 | ASSERT(add5ifGreaterThan2(3) == 8) // tests if (a > 2) case 62 | ``` 63 | 64 | #### More Info 65 | 66 | Here is a link to the wikipedia article for more depth on unit testing practice and history: [Unit_testing](https://en.wikipedia.org/wiki/Unit_testing). 67 | 68 | 69 | ### Testing Frameworks 70 | 71 | Unit testing frameworks make it easier to automate testing. Many languages have frameworks named like JUnit (for Java) or PyUnit (for Python). In C/C++, several frameworks are available, including: 72 | 73 | * [CppUTest](http://cpputest.github.io/) - A unit test framework for C++ 74 | * [Boost C++ Unit Test Framework](http://www.boost.org/doc/libs/1_35_0/libs/test/doc/components/utf/index.html) - This is the test framework used by the popular Boost library for C++ 75 | * [Typemock](https://www.typemock.com/) - a commercial Test Package 76 | * [Cantata](http://www.qa-systems.com/tools/cantata) - a commercial Test Package 77 | * [Google Test](https://github.com/google/googletest) - we'll be using this here. Google Test is a free opensource framework using special macros for asserting when code doesn't perform as expected. 78 | * [Catch](https://github.com/philsquared/Catch) - Catch is a test framework for C 79 | 80 | We'll be using Google Test (gtest) in this example. 81 | 82 | Here is the link to the project source 83 | [Google Test](https://github.com/google/googletest) 84 | 85 | ### Installing Google Test 86 | 87 | On Ubuntu Linux, install gtest using the following commands: 88 | 89 | ```bash 90 | sudo apt-get install libgtest-dev 91 | sudo apt-get install cmake 92 | cd /usr/src/gtest 93 | sudo cmake CMakeLists.txt 94 | sudo make 95 | sudo cp *.a /usr/lib 96 | sudo mkdir /usr/local/lib/googletest 97 | sudo ln -s /usr/lib/libgtest.a /usr/local/lib/gtest/libgtest.a 98 | sudo ln -s /usr/lib/libgtest_main.a /usr/local/lib/gtest/libgtest_main.a 99 | ``` 100 | 101 | You can read more about the Google Test project here: [Testing Primer](https://github.com/google/googletest/blob/master/googletest/docs/Primer.md) 102 | 103 | ### Testing vs Continuous Integration 104 | 105 | Once you've written unit tests and run them locally, CI services (such as Travis-CI, GitHub Actions, Circle-CI, Jenkins, and others) can automatically run your test suites and report the results **every time you check in**. CI can be configured to accept or reject your code based on the tests passing, and can even deploy your code automatically if it passes all the tests. This is called Continuous Deployment, or CD. 106 | 107 | ### Using Travis-CI as a CI Provider 108 | 109 | Travis-CI 110 | Travis-CI looks in the .travis.yml file to see how to run the code. It compiles lib.c and example.c into lib.o and example.o, and then links them to produce the executable example.out. The test suite is run, and the exit code is used to determine if the build passes. 111 | 112 | ### Using Github Actions as CI Provider 113 | 114 | GitHub Actions work similarly. When code is pushed to the main branch, GitHub triggers an action to look at the ./github/workflows/ci.yml file, which specifies the environment, builds the code, runs the test script, and reports success or failure. 115 | 116 | ### Code Coverage 117 | 118 | Code coverage is achieved using gcov from the gcc test suite. To see the code coverage: 119 | 120 | ```bash 121 | make clean 122 | make 123 | ./test-library.out 124 | gcov lib.c 125 | ``` 126 | 127 | This generates the file lib.c.gcov, which can be viewed in any text editor. Lines with #### have never been run. 128 | 129 | ## FAQ 130 | 131 | Q: What's the point of this repo if it doesn't do anything? 132 | A: It's a simple example of using Travis-CI for testing purposes. 133 | 134 | Q: How can I make it fail for testing purposes? 135 | A: Modify a line in main.c to make it fail, or use other methods to test failure cases. 136 | 137 | Q: Why isn't there a proper unit test framework? 138 | A: This is a barebones test of integration and badge service. 139 | 140 | ## License 141 | 142 | (OSI Approved BSD 2-clause) 143 | 144 | version 1.0.3 (added GitHub Actions support) 145 | version 1.0.2 (updated for travis-ci.com transition) M. A. Chatterjee 146 | 147 | (c) 2016 and later M. A. Chatterjee 148 | -------------------------------------------------------------------------------- /lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | @lib.c - header file for travis-ci example library 4 | 5 | @copy Copyright (C) <2012> 6 | @author M A Chatterjee 7 | @version 0.21 M. A. Chatterjee 8 | 9 | This file contains header defintions for travis-ci code testing example. 10 | 11 | @license: 12 | Copyright (c) 2011-2016, M. A. Chatterjee 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, this 19 | list of conditions and the following disclaimer. 20 | 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #include "lib.h" 39 | 40 | /* 41 | The "libary" begins here! 42 | Its just a bunch of simple functions for showing the test environment not any thing 'real' 43 | 44 | */ 45 | 46 | 47 | 48 | /* integer bitwise AND */ 49 | int op_and (int x, int y) { 50 | return x&y; 51 | } 52 | 53 | /* integer bitwise OR */ 54 | int op_or (int x, int y) { 55 | return x|y; 56 | } 57 | 58 | /* integer bitwise XOR */ 59 | int op_xor (int x, int y) { 60 | return x^y; 61 | } 62 | 63 | /* integer bitwise XNOR */ 64 | int op_xnor (int x, int y) { 65 | return ~(x^y); 66 | } 67 | 68 | /* integer add */ 69 | int op_add (int x, int y) { 70 | return x+y; 71 | } 72 | 73 | /* integer sub */ 74 | int op_sub (int x, int y) { 75 | return x-y; 76 | } 77 | 78 | /* integer mul */ 79 | int op_mul (int x, int y) { 80 | return x*y; 81 | } 82 | 83 | 84 | -------------------------------------------------------------------------------- /lib.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | @lib.h - header file for travis-ci example for github 4 | 5 | @copy Copyright (C) <2017> 6 | @author M A Chatterjee 7 | @version 1.0 M. A. Chatterjee 8 | 9 | This file contains header defintions for travis-ci code testing example. 10 | 11 | @license: 12 | Copyright (c) 2011-2016, M. A. Chatterjee 13 | All rights reserved. 14 | 15 | Redistribution and use in source and binary forms, with or without 16 | modification, are permitted provided that the following conditions are met: 17 | 18 | * Redistributions of source code must retain the above copyright notice, this 19 | list of conditions and the following disclaimer. 20 | 21 | * Redistributions in binary form must reproduce the above copyright notice, 22 | this list of conditions and the following disclaimer in the documentation 23 | and/or other materials provided with the distribution. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 33 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | 36 | */ 37 | 38 | #ifndef __lib_h__ 39 | #define __lib_h__ 40 | 41 | 42 | #ifdef __cplusplus 43 | extern "C" 44 | { 45 | #endif 46 | 47 | /** The "libary" begins here */ 48 | 49 | /* integer bitwise AND */ 50 | int op_and (int x, int y); 51 | 52 | /* integer bitwise OR */ 53 | int op_or (int x, int y); 54 | 55 | /* integer bitwise XOR */ 56 | int op_xor (int a, int b); 57 | 58 | /* integer bitwise XNOR */ 59 | int op_xnor (int a, int b); 60 | 61 | /* integer add */ 62 | int op_add (int x, int y); 63 | 64 | /* integer sub */ 65 | int op_sub (int x, int y); 66 | 67 | /* integer mul */ 68 | int op_mul (int x, int y); 69 | 70 | 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | 75 | #endif /* __lib_h__ */ 76 | 77 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | # makefile for posix tests (simple test lib coverage for embedded systems) 2 | # @author M A Chatterjee 3 | 4 | # test coverage is achieved usding gcov (part of gcc suite) 5 | # this is done with the flags -ftest-coverage -fprofile-arcs 6 | # see run_coverage_test.sh to see how to call code coverage tests 7 | CC=gcc 8 | CFLAGS = -I. -Wall -ftest-coverage -fprofile-arcs 9 | DEPS = lib.h 10 | OBJ = lib.o test-library.o 11 | 12 | %.o: %.c $(DEPS) 13 | $(CC) -c -o $@ $< $(CFLAGS) 14 | 15 | test-library.out: $(OBJ) 16 | gcc -o $@ $^ $(CFLAGS) -lm -lncurses -Os 17 | 18 | clean : 19 | rm *.o *.asm *.lst *.sym *.rel *.s *.gc* -f *.info 20 | 21 | -------------------------------------------------------------------------------- /run_coverage_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #this shell script calls the code coverage testing program gcov (part of the gcc suite) 4 | #you can run each command on your own at the command line 5 | 6 | #fist clean all object files 7 | make clean 8 | 9 | #compile all the c files, link etc 10 | make 11 | 12 | # run the example.out program ... with test coverage (see makefile for flags) 13 | ./test-library.out 14 | 15 | # gcov is the gcc suite test coverage program. We're interested in the coverage 16 | # the lib.c file. 17 | gcov lib.c 18 | 19 | # now the code coverage is in this file: 20 | # lib.c.gcov 21 | # which can be viewed in any text editor 22 | -------------------------------------------------------------------------------- /test-library.c: -------------------------------------------------------------------------------- 1 | /* 2 | @main.c - simple test file example file for continuous integration example library 3 | 4 | @copy Copyright (C) <2012> 5 | @author M A Chatterjee 6 | 7 | This file contains header defintions for travis-ci code testing example. 8 | 9 | @license: 10 | Copyright (c) 2016 and later, M. A. Chatterjee 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright notice, this 17 | list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright notice, 20 | this list of conditions and the following disclaimer in the documentation 21 | and/or other materials provided with the distribution. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | 34 | */ 35 | 36 | #include 37 | #include "lib.h" 38 | 39 | #define S_OK (0) 40 | #define E_FAIL (-1) 41 | 42 | 43 | /* ************************************************ 44 | simple test cases for the library functions 45 | ************************************************ 46 | */ 47 | 48 | 49 | /* test cases for op_and() function */ 50 | int test_and() { 51 | 52 | if (op_and(3,4) != (3&4)) 53 | return E_FAIL; 54 | 55 | if (op_and(2,7) != (2&7)) 56 | return E_FAIL; 57 | 58 | // un comment me to make this fail! 59 | //if ((f_ib_and(2,7) == (2&7)) 60 | // return E_FAIL;) 61 | 62 | return S_OK; 63 | } 64 | 65 | /* test cases for op_or() function */ 66 | int test_or() { 67 | if (op_or(3,4) != (3|4)) 68 | return E_FAIL; 69 | 70 | return S_OK; 71 | } 72 | 73 | /* test cases for op_xor() function */ 74 | int test_xor() { 75 | if (op_xor(3,4) != ((3^4))) 76 | return E_FAIL; 77 | return S_OK; 78 | } 79 | 80 | 81 | /* test cases for op_xnor() function */ 82 | int test_xnor() { 83 | if (op_xnor(3,4) != (~(3^4))) 84 | return E_FAIL; 85 | return S_OK; 86 | } 87 | 88 | /* test cases for op_add() function */ 89 | int test_add() { 90 | if (op_add(3,4) != (3+4)) 91 | return E_FAIL; 92 | return S_OK; 93 | } 94 | 95 | 96 | /* test cases for op_sub() function */ 97 | int test_sub() { 98 | if (op_sub(3,4) != (3-4)) 99 | return E_FAIL; 100 | return S_OK; 101 | } 102 | 103 | 104 | /* test cases for op_mul() function */ 105 | int test_mul() { 106 | if (op_mul(3,4) != (3*4)) 107 | return E_FAIL; 108 | return S_OK; 109 | } 110 | 111 | /* ************************************************ 112 | this is a simple test suite. 113 | normally you would run cppUnit or some other 114 | more general purpose test framework. 115 | */ 116 | int run_tests() { 117 | if (E_FAIL == test_and()) { 118 | printf("failed test_and()\n"); 119 | return E_FAIL; 120 | } 121 | 122 | if (E_FAIL == test_or()) { 123 | printf("failed test_or()\n"); 124 | return E_FAIL; 125 | } 126 | 127 | if (E_FAIL == test_xor()){ 128 | printf("failed test_xor()\n"); 129 | return E_FAIL; 130 | } 131 | 132 | if (E_FAIL == test_xnor()){ 133 | printf("failed test_xnor()\n"); 134 | return E_FAIL; 135 | } 136 | 137 | if (E_FAIL == test_add()){ 138 | printf("failed test_add()\n"); 139 | return E_FAIL; 140 | } 141 | 142 | if (E_FAIL == test_sub()){ 143 | printf("failed test_sub()\n"); 144 | return E_FAIL; 145 | } 146 | 147 | 148 | if (E_FAIL == test_mul()){ 149 | printf("failed test_mul()\n"); 150 | return E_FAIL; 151 | } 152 | 153 | return S_OK; 154 | } 155 | 156 | 157 | /* 158 | This main function only runs all the test code. 159 | If successful it returns S_OK which is equal to the numerical value of 0. 160 | Any other value is considered a failure. 161 | 162 | */ 163 | int main() 164 | { 165 | int result; 166 | 167 | printf("Running Example tests .. \n"); 168 | result = run_tests(); 169 | 170 | if (result == S_OK) 171 | printf ("tests passed.\n"); 172 | else 173 | printf ("tests failed.\n"); 174 | 175 | return result; /* remember the value 0 is considered passing in a travis-ci sense */ 176 | 177 | } --------------------------------------------------------------------------------