1

I am new at testing embedded systems with ceedling. I was wondering if there is a good place to start in terms of learning how to use ceedling.

The project that I am working on its an embedded System for a CubeSat Project and we need a way to test our code.

schneebuzz
  • 348
  • 1
  • 2
  • 10
Addi
  • 49
  • 2
  • 5

2 Answers2

1

The first thing you should understand is that first and foremost Ceedling or any unit test framework is intended to test your code and by extension your ultimate project. You typically test your code on your PC using a standards based compiler of some sort, not necessarily your cross compiler for your embedded system. You can run ceedling generated tests on a target but you probable don't want to.

The best book on this subject (not perfect but still darn good) is James W. Grenning's Test Driven Development for Embedded C (Pragmatic Programmers).

I have a personal GIST on setting up under older Windows here. Mostly notes to myself on getting Ruby and GCC on windows.

Under Linux Ceedling is super easy to setup and run.

  1. confirm you have gcc available
  2. confirm you have ruby with gem
  3. gem install ceedling
  4. ceedling

That's it. If you are adapting to a new project you will need to fiddle around with the project.yml file to tell ceedling where your source files and include files are, and where you want your test files to go. This can be challenging on some project structures but if all else fails you just put ever folder by name in your project.yml file (not best but ultimate fallback for crazy messed up projects) There is other learning curve stuff like ceedling test_xxx.c files are sort of magic in that they contain your tests but also act like a linker control file. Every include file in the test_xxx.c file is assumed to have a corresponding translation unit (.c file) with the same base name. Ceedling will search it out and compile it into your test. If you want to exclude that code but need some of the dependencies you change the include file name to include the word mock to automatically mock the interface so foo.h becomes mock_foo.h and will create mock functions for all the declared functions found in the header. If you don't have a header/tranalation_unit name pair, you can tell ceedling to compile and link a file by putting its name in a macro called TEST_FILE. So if you have no foo.h but need foo.c:

TEST_FILE("foo.c")

There is a bunch of other great resources on the Throw The Switch page. Hope that helps. I have never needed to pull the tool from github directly but if you want to send them patches I suppose that is another way, but they put so much work into making it friction-less to setup and start using, I would start with the ruby method first.

Side note there are some cool unit testing hooks in the module_generator plugin now to automatically generate stubs for testing which may be very useful during on target tests.

bd2357
  • 704
  • 9
  • 17
0

There are numerous ways of getting into it. My preference is to clone ceedling (git clone https://github.com/ThrowTheSwitch/Ceedling.git && git submodule update --init --recursive) and run an example to see how it works.

To make the examples/temp_sensor work you need to make three modifications:

  • project.yml - plugins, load_paths should be ../../plugins
  • rakefile.rb - PROJECT_CEEDLING_ROOT should be "../.."
  • lib/ceedling/rakefile.rb - add a line referencing diy/test

Here is a diff with the modifications I made on master (git commit 09a04cb55a86):

diff --git a/examples/temp_sensor/project.yml b/examples/temp_sensor/project.yml
index ec9a45e..a327f5b 100644
--- a/examples/temp_sensor/project.yml
+++ b/examples/temp_sensor/project.yml
@@ -58,7 +58,7 @@

 :plugins:
   :load_paths:
-    - vendor/ceedling/plugins
+    - ../../plugins
   :enabled:
     - stdout_pretty_tests_report
     - module_generator
diff --git a/examples/temp_sensor/rakefile.rb b/examples/temp_sensor/rakefile.rb
index 1b534d2..82d2e64 100755
--- a/examples/temp_sensor/rakefile.rb
+++ b/examples/temp_sensor/rakefile.rb
@@ -1,4 +1,4 @@
-PROJECT_CEEDLING_ROOT = "vendor/ceedling"
+PROJECT_CEEDLING_ROOT = "../.."
 load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb"

 Ceedling.load_project
diff --git a/lib/ceedling/rakefile.rb b/lib/ceedling/rakefile.rb
index 37001ba..be6b620 100644
--- a/lib/ceedling/rakefile.rb
+++ b/lib/ceedling/rakefile.rb
@@ -9,6 +9,7 @@ CEEDLING_RELEASE = File.join(CEEDLING_ROOT, 'release')
 $LOAD_PATH.unshift( CEEDLING_LIB )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'unity/auto') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/lib') )
+$LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'diy/test') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'cmock/lib') )
 $LOAD_PATH.unshift( File.join(CEEDLING_VENDOR, 'deep_merge/lib') )

Run the example by running rake test from within examples/temp_sensor.

You need ruby (for rake) and gcc installed for the temp_sensor example.

Once you've worked out the format of the example/temp_sensor/rakefile.rb and example/temp_sensor/project.yml file the key work is within the examples/temp_sensor/test/Test... files.

John
  • 59
  • 4
  • 1
    The use of rake to drive ceedling was deprecated a few years ago. So much easier to just use the gem, and this is from someone who knows almost nothing about ruby. See my answer. – bd2357 May 05 '20 at 16:32