ユニットCテスト-簡単なことは何もない

記事「組み込みシステムのテスト」とそのコメントを読んだ後、多くのHabrovskの人々が「組み込みC(プラグマティックプログラマー)のテスト駆動開発」Unityフレームワークに精通しているが、 throwtheswitch.orgから提供します



これらのツールを使用した経験を簡単に共有したいと思います。



私自身について



偶然、テスト(ユニット、統合、システム、ストレス)を通じて組み込みシステムのプログラミングの経験を積みました。 3年間、幸運にもジュニアから、他の専門家のコードをカバーするテストを作成し、TDD方法論を使用してシステムを開発した経験のあるシニアになりました。



約束された



上記のUnityフレームワークは非常にシンプルで使いやすいです。 しかし、これは氷山の一角にすぎません。 throwtheswitch.orgページでは、次のツールを使用できます。



CMockは、テスト用の模擬Cコードを自動的に生成できるツールです。 Rubyで書かれています。 私は、3年間、自分の手でモックを「生成」した人が、C開発者への単なる贈り物であると断言します。 しかし、私の意見では、次のツールなしで自律的に使用することは合理的ではありません。



著者自身によると、Ceedlingはビルドシステム全体です。 しかし、本質的には、仕事に必要なのはそれだけです。 このパッケージには、Unity(値の「テストランナー」と「ストライカー」)、CMock(モックジェネレーター)、およびruby makeによるコマンドラインサポートが必要です。



その他-この奇妙な見出しの下では、CExceptionという非常に便利なツールです。 ある種の例外を取得できる非常に小さなCライブラリ。 しかし、私は誤解しません。 プロジェクトで使用できませんでした。



このさまざまな素晴らしいものに望まれるものを残しているのは、チュートリアルだけです。 彼は、いわばそこにはいません。 すべては明確ですが、初心者からどこから始めるかは大きな問題です。 私は状況を修正しようとします。



まず、Ceelingを正しくインストールし、 ここに示すようにパフォーマンスをテストする必要があります



インストール後、次のコマンドを使用してプロジェクトのフォルダーとテスト環境を作成します。



ceedling new MyNewProject
      
      





その結果、MyNewProjectフォルダーが作成され、その中に次のフォルダーとファイルが生成されます。





最初のテストを作成します。



test_calc.cファイルをテストフォルダーに次の内容で入れます。



 #include "unity.h" #include "calc.h" void setUp(void) { } void tearDown(void) { } void test_add( void ) { int result = 0; result = calc_add(2,2); TEST_ASSERT_EQUAL_INT( 4, result ); }
      
      





次のコマンドでテストを実行します。



 ceedling test:test_calc.c
      
      





結果が期待されます。 テストがあり、コードはありません。 プロジェクトを組み立てることができませんでした。



コードを追加します。

srcフォルダーに2つのファイルを配置します。



「Calc.h」

 #ifndef CALC_H #define CALC_H int calc_add(int a, int b); #endif
      
      





「Calc.c」

 #include "calc.h" int calc_add(int a, int b) { return a + b; }
      
      





アセンブリを繰り返し、テストを実行しようとします。



 ceedling test:test_calc.c
      
      





すべてが正しく完了したら、コンソールにテスト結果が表示されます。



 Test 'test_calc.c' ------------------ Compiling test_calc_runner.c... Compiling test_calc.c... Compiling calc.c... Compiling unity.c... Compiling cmock.c... Linking test_calc.out... Running test_calc.out... ------------------------- OVERALL UNIT TEST SUMMARY ------------------------- TESTED: 1 PASSED: 1 FAILED: 0 IGNORED: 0
      
      





この短い例は、テストランナーが生成され、アセンブリに自動的に追加されたことを示しています。 そのコードはbuild / test / runnersフォルダーにあります。



タスクを複雑にして、「バトル」ファイルが別のプログラムモジュール(rules.cなど)でチェックされる特定の条件下でのみカウントできるようにする必要があるとします。 以下を説明するためにコードを変更します。



「Calc.c」

 #include "calc.h" #include "rules.h" int calc_add(int a, int b) { if (rules_is_addition_allowed()) { return a + b; } return 0; }
      
      





別のファイルをsrcフォルダーに追加します。



「Rules.h」

 #ifndef RULES_H #define RULES_H int rules_is_addition_allowed(void); #endif
      
      





rules_is_addition_allowed()関数の定義がないため、テストの実行は失敗します。



CMockを使用します。

次のようにテストを変更します。



 #include "unity.h" #include "calc.h" #include "mock_rules.h" void setUp(void) { } void tearDown(void) { } void test_add( void ) { int result = 0; rules_is_addition_allowed_ExpectAndReturn(1); result = calc_add(2,2); TEST_ASSERT_EQUAL_INT( 4, result ); } void test_add_off_nominal( void ) { int result = 0; rules_is_addition_allowed_ExpectAndReturn(0); result = calc_add(2,2); TEST_ASSERT_EQUAL_INT( 0, result ); }
      
      





したがって、「#include」mock_rules.h」という1つの指示だけで自動的に生成されたモックを取得しました。このファイルのソースコードは、build / test / mocksディレクトリにあります。



ご予約



1.このフレームワークは、PCでコードをテストするためにのみ使用します 。 これにより、開発中のソフトウェアのアーキテクチャに対する特定のルールが決まります。 実際のハードウェアで単体テストを実行しても意味がありません。 HAL-動作するかどうかのいずれかであり、手動でテストされます(状況に対する私のビジョン)。

2.複数のスレッドのテストにこのフレームワークを使用しません 。 このツールのスレッドの安全性は私によって調査されていません。

3.この記事では、コードやテストを正しく記述する方法については説明しませんが、上記の開発ツールについて簡単に説明します。



All Articles