- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试为嵌入式应用程序开发一项新功能,并且我想使用测试驱动的方法来实现。
该项目是用纯 C 语言编写的,正在使用 IAR Embedded Workbench 6.60.1.5104 进行开发。我的目标是 LPC1788,这是一个 Cortex-M3 设备,所有开发都是在 64 位 Windows 7 机器上完成的。现在我更赞成让单元测试在 PC 上运行,而不是在目标硬件上运行(RAM 非常有限)。
我看到一本关于这个主题的有用的书,叫做 Test Driven Development for Embedded C这让我转向了 Unity、CppUTest、Ceedling 等工具。在研究了这些东西之后,我认为我最好的选择是为我的项目配置 Ceedling(使用 Unity)。但是,我不确定我需要采取哪些步骤来配置 Ceedling 以使用我当前的 IAR 工具链。
我已经安装了 Ceedling 并创建了“blinky”示例项目,我正在尝试使用 IAR 工具链构建和测试它。我已将 iccarm.exe
添加到我的路径并编辑了 blinky/project.yml
,如下所示:
---
# Notes:
# This is a fully tested project that demonstrates the use
# of a timer ISR to blink the on board LED of an Arduino UNO
:project:
:use_exceptions: FALSE
:use_test_preprocessor: TRUE
:use_auxiliary_dependencies: TRUE
:build_root: build
:release_build: TRUE
:test_file_prefix: test_
#You'll have to specify these
:environment:
- :mcu: atmega328p
- :f_cpu: 16000000UL
- :serial_port: COM8 #change this to the serial port you are using!!!
- :objcopy: avr-objcopy
# Uncomment these lines if you are using windows and don't have these tools in your path
# - :path:
# - C:\mingw\bin
# - C:\WinAVR-20100110\bin
# - C:\WinAVR-20100110\utils\bin
# - #{ENV['PATH']}
:extension:
:executable: .bin
:release_build:
:output: blinky
:paths:
:test:
- +:test/**
- -:test/support
:source:
- src/**
:support:
- test/support
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines []
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
:tools:
:release_compiler:
:executable: avr-gcc
:arguments:
- ${1}
- -DTARGET
- -DF_CPU=#{ENV['F_CPU']}
- -mmcu=#{ENV['MCU']}
- -Iinclude/
- -Wall
- -Os
- -c
- -o ${2}
:release_linker:
:executable: avr-gcc
:arguments:
- -mmcu=#{ENV['MCU']}
- ${1}
- -o ${2}.bin
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:tools:
:test_file_preprocessor:
:executable: iccarm
:name: 'IAR test file preprocessor'
:test_includes_preprocessor:
:executable: iccarm
:name: 'IAR test includes preprocessor'
:test_compiler:
:executable: iccarm
:name: 'IAR test compiler'
:test_linker:
:executable: iccarm
:name: 'IAR test linker'
:release_compiler:
:executable: iccarm
:name: 'IAR release compiler'
:release_linker:
:executable: iccarm
:name: 'IAR release linker'
:plugins:
:load_paths:
- vendor/ceedling/plugins
:enabled:
- stdout_pretty_tests_report
- module_generator
...
这与默认的 project.yml
之间的唯一区别是第二个 :tools
部分下的内容。
我的猜测是我正朝着正确的方向前进,但我不确定 iccarm.exe
是否是用于工具链所有这些部分的正确可执行文件以及我的参数需要通过。
如果我可以配置 Ceedling 以使用 IAR 工具链构建和测试 blinky 项目,我希望我应该能够为我的实际项目应用相同的配置。如果我现在尝试运行 rake
,我会得到以下输出:
$ rake
Test 'test_BlinkTask.c'
-----------------------
rake aborted!
Errno::ENOENT: No such file or directory @ rb_sysopen - build/test/preprocess/files/test_BlinkTask.c
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb:18:in `readlines'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_extractor.rb:18:in `extract_base_file_from_preprocessed_expansion'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_file_handler.rb:14:in `preprocess_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:40:in `preprocess_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:12:in `block in setup'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator_helper.rb:33:in `preprocess_test_file'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/preprocessinator.rb:25:in `preprocess_test_and_invoke_test_mocks'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/test_invoker.rb:42:in `block in setup_and_invoke'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/test_invoker.rb:32:in `setup_and_invoke'
C:/Users/davidfallah/Documents/IAR Projects/blinky/vendor/ceedling/lib/ceedling/tasks_tests.rake:11:in `block (2 levels) in <top (required)>'
Tasks: TOP => default => test:all
(See full trace by running task with --trace)
--------------------
OVERALL TEST SUMMARY
--------------------
No tests executed.
我假设这是因为测试文件预处理器应该在 build/test/preprocess/files
目录下复制测试文件,目前还没有发生。
经过一番挖掘,我发现了这个 example configuration file for Unity看起来可能会有帮助。它适用于像我正在使用的 IAR EW/Cortex M3 环境。这可能会指示我需要在我的 Ceedling project.yml
中指定哪些配置选项:
如果我能让 Ceedling 使用 IAR 工具链构建和测试 blinky
项目,我希望我可以调整它以用于我的实际项目。任何帮助将不胜感激。
最佳答案
这是一场斗争,但我相信我已经设法配置 Ceedling 来帮助测试我的项目。希望这对任何希望在 IAR 项目中使用 Ceedling 的人都有用。
Ceedling CLI 有一个命令 ( ceedling new <proj_name>
),允许您使用 Ceedling 期望的结构创建新项目。您还可以指定一个现有项目的名称,在这种情况下,它只会添加必要的文件以使其与 Ceedling 兼容,这就是我对我的项目所做的。
作为引用,执行此步骤后我的项目结构如下所示:
.
├── build
│ ├── artifacts
│ │ └── test
│ ├── docs
│ ├── exe
│ ├── list
│ ├── logs
│ ├── obj
│ ├── temp
│ └── test
│ ├── cache
│ ├── dependencies
│ ├── list.i
│ ├── mocks
│ ├── out
│ ├── results
│ ├── runners
│ └── tests.map
├── project.yml
├── rakefile.rb
├── src
│ └── main
│ ├── c
│ │ ├── canDatabase.c
│ ├── include
│ │ ├── canDatabase.h
│ ├── python
│ └── resources
├── test
│ ├── support
│ └── test_canDatabase.c
├── <my_project>.dep
├── <my_project>.ewd
├── <my_project>.ewp
├── <my_project>.eww
├── vendor
│ └── ceedling
│ ├── docs
│ ├── lib
│ ├── plugins
│ └── vendor
└── version.properties
之后,我查看了 IAR 工具的引用手册,并研究了构建示例项目时 IAR Embedded Workbench 的输出,正如@user694733 所建议的那样。我使用这些信息来编辑我的 project.yml
如下所示:
:project:
:use_exceptions: FALSE
:use_test_preprocessor: FALSE
:use_auxiliary_dependencies: TRUE
:build_root: build
:release_build: FALSE
:test_file_prefix: test_
:environment:
- :path:
- 'C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin'
- 'C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\common\bin'
- #{ENV['PATH']}
:extension:
:executable: .out
:paths:
:test:
- +:test/**
- -:test/support
:source:
- src/main/c/**
- src/main/include/**
- src/main/resources/**
:support:
- test/support
:defines:
:commmon: &common_defines []
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
:cmock:
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
- :ignore
- :callback
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
:tools:
:test_compiler:
:executable: iccarm
:name: 'IAR test compiler'
:arguments:
- -D _DLIB_FILE_DESCRIPTOR=1
- --debug
- --endian=little
- --cpu=Cortex-M3
- -e
- --fpu=None
- -Ol
- --preprocess "build/test/list"
- --dlib_config "C:/Program Files (x86)/IAR Systems/Embedded Workbench 6.5/arm/INC/c/DLib_Config_Normal.h"
- -I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE
- -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
- -o "${2}"
- --diag_suppress=Pa050
- '"${1}"'
:test_linker:
:executable: ilinkarm
:name: 'IAR test linker'
:arguments:
- --vfe
- --redirect _Printf=_PrintfFull
- --redirect _Scanf=_ScanfFull
- --semihosting
- --config "C:/Program Files (x86)/IAR Systems/Embedded Workbench 6.5/arm/config/generic_cortex.icf"
- --map "build/test/tests.map"
- -o "${2}"
- '"${1}"'
:test_fixture:
:executable: cspybat
:name: 'CSpyBat test runner'
:arguments:
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armproc.dll"'
- '"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armsim2.dll"'
- '"${1}"'
- --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.5\arm\bin\armbat.dll"
- --backend -B
- --endian=little
- --cpu=Cortex-M3
- --fpu=None
- --semihosting
:plugins:
:load_paths:
- vendor/ceedling/plugins
:enabled:
- stdout_pretty_tests_report
- module_generator
...
这似乎是测试设计用于 Cortex-M3 设备的代码的合适配置。
我还编辑了 rakefile.rb
以确保在每次测试运行之前清理生成的测试文件,因为这是让测试结果得到一致打印所必需的。
PROJECT_CEEDLING_ROOT = "vendor/ceedling"
load "#{PROJECT_CEEDLING_ROOT}/lib/ceedling.rb"
Ceedling.load_project
task :default => %w[ clean test:all ]
然后我能够定义和运行单元测试。以下是 test_canDatabase.c
的摘录:
#include "unity.h"
#include "canDatabase.h"
uint32_t actualId;
uint8_t actualPayload[8];
uint8_t actualPayloadLen;
uint8_t actualCanPort;
void mockHandler(uint32_t id, uint8_t payload[8], uint8_t payloadLen, uint8_t canPort)
{
actualId = id;
actualPayloadLen = payloadLen;
actualCanPort = canPort;
for (int i=0; i < payloadLen; i++)
{
actualPayload[i] = payload[i];
}
}
void setUp(void)
{
actualId = 0;
actualPayloadLen = 0;
actualCanPort = 0;
for (int i=0; i < 8; i++)
{
actualPayload[i] = 0;
}
CANDB_Init(mockHandler);
}
void tearDown(void) {}
void test_Register_Tx_Definition()
{
// GIVEN a CAN Tx message definition.
CAN_TX_MESSAGE_DEFINITION_T definition;
definition.id = 0;
// WHEN we register the definition in the CAN database.
int err = CANDB_RegisterTxDefinition(definition);
// THEN the database should return SUCCESS (0x0).
TEST_ASSERT_EQUAL_MESSAGE(0x0, err, "Registration should succeed");
}
void test_Register_Tx_Definition_Twice()
{
// GIVEN a CAN Tx message definition.
CAN_TX_MESSAGE_DEFINITION_T definition;
definition.id = 0;
// WHEN we register the definition once.
CANDB_RegisterTxDefinition(definition);
// AND we register the definition again.
int err = CANDB_RegisterTxDefinition(definition);
// THEN the database should return SUCCESS (0x0).
TEST_ASSERT_EQUAL_MESSAGE(0x0, err, "Re-registration should succeed");
}
我现在可以通过从终端调用“ceedling”来运行自动化测试(项目根目录是当前工作目录):
$ ceedling
---------------------
BUILD FAILURE SUMMARY
---------------------
Unit test failures.
Cleaning build artifacts...
(For large projects, this task may take a long time to complete)
Test 'test_canDatabase.c'
-------------------------
Generating runner for test_canDatabase.c...
Compiling test_canDatabase_runner.c...
Compiling test_canDatabase.c...
Compiling unity.c...
Compiling canDatabase.c...
Compiling cmock.c...
Linking test_canDatabase.out...
Running test_canDatabase.out...
-----------
TEST OUTPUT
-----------
[test_canDatabase.c]
- ""
- " IAR C-SPY Command Line Utility V6.6.0.2752"
- " Copyright 2000-2013 IAR Systems AB."
- ""
- ""
-------------------
FAILED TEST SUMMARY
-------------------
[test_canDatabase.c]
Test: test_Register_More_Than_Max_Allowed_Definitions
At line (84): "Expected 1 Was 0. Registration > CANDB_MAX_TX_DEFINITIONS should fail"
Test: test_Activate_Tx_Definition_With_Hardcoded_Payload
At line (124): "Expected 0x00000001 Was 0x00000000. Incorrect ID"
--------------------
OVERALL TEST SUMMARY
--------------------
TESTED: 4
PASSED: 2
FAILED: 2
IGNORED: 0
关于c - 如何为 IAR Embedded Workbench 项目配置 Ceedling?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41140188/
我想使用 ceedling 对 STM32 系列的 C 代码进行单元测试。我按照他们在 GitHub Ceedling 上的页面所示安装了它并成功运行示例测试。 project.yml 文件我已经修改
我有一个嵌入式系统项目,正在使用 Ceedling(=Unity 和 Cmock)进行测试。 在一个测试用例中,被测代码就是这么简单: uint32_t zero = eeprom_read_dwor
我有一个嵌入式系统项目,正在使用 Ceedling(=Unity 和 Cmock)进行测试。 在一个测试用例中,被测代码就是这么简单: uint32_t zero = eeprom_read_dwor
我对使用 Ceedling/Unity 还很陌生。我有一个模块,我正在通过给它不同的输入测试点并检查输出值来测试它。但我需要这样做很多次。这与我尝试过的类似(使用“for”循环): /*Example
我正在为嵌入式应用程序开发一项功能,我正在使用 Ceedling(构建在 Unity 测试框架之上)对其进行测试。我遇到的一个问题是我需要在 C 源文件中使用 Ceedling 未编译/链接到我的单元
我在 Ubuntu 20.04 上使用 Jenkins 来自动化我的构建过程。有两个项目给了我,它们是高度耦合的。我将努力将两者分开,但首先我需要设置一些测试。这两个项目是 PNE 和 BLDC 供引
我正在尝试使用 Ceedling 为我的 C 项目创建单元测试。我在终端写道:-ceedling 新的 My_Project_NameCeedling 创建了一个名为“My_Project_Name”
我想在使用 Ceedling 时调试被测 C 源代码。我发现可以使用以下命令,但无法设置断点。似乎没有生成符号信息。我使用 project.yml 中的默认设置,并检查了 -g 选项在 default
我一直在为 STM32 设置 Ceedling。 howto 非常稀缺,到目前为止,我几乎什么都没用谷歌搜索。幸运的是,该框架相对于它的大小而言是相对透明的。 This是 PIC 配置。我设置了类似的
我正在使用 Throw The Switch's Ceedling 为 C 项目编写单元测试/Unity/CMock 组合作为单元测试框架。 在我的一个单元测试中使用 mqueue.h 时,我遇到了一
我正在尝试为嵌入式应用程序开发一项新功能,并且我想使用测试驱动的方法来实现。 该项目是用纯 C 语言编写的,正在使用 IAR Embedded Workbench 6.60.1.5104 进行开发。我
是否基本上可以模拟要测试的文件的功能? 例如我想测试由这些函数组成的文件 self_test.c: #include "self_test.h" uint8_t function_1(uint8_t
我是一名优秀的程序员,十分优秀!