官术网_书友最值得收藏!

Functional tests

Writing test cases before writing the code is generally considered an optimal practice in modern programming. Writing tests first not only speeds up the development phases, but also improves the structure of the workflow. By setting clear and measurable goals from the beginning, it is harder to introduce conceptual defects in the design of the single components, and also forces a clearer separation among the modules. More specifically, an embedded developer has less possibility to verify the correct behavior of the system through direct interaction, thus test-driven development (TDD) is the preferred approach for the verification of the single components as well as the functional behavior of the entire system, as long as the expected results can be directly measurable from the host system.

However, it must be considered that testing often introduces dependencies on specific hardware, and sometimes the output of an embedded system can only be validated through specific hardware tools, or in a very unique and peculiar usage scenario. In all these cases, the usual TDD paradigm is less applicable, and the project can instead benefit from a modular design, to give the possibility to test as many components as possible in a synthetic environment, such as emulators or unit test platforms.

Writing tests often involves programming the host so that it can retrieve information about the running target while the embedded software is executing, or alongside an ongoing debugging session, while the target executes in between breakpoints. The target can be configured to provide immediate output through a communication interface, such as a UART-based serial port, which can in turn be parsed by the host. It is usually more convenient to write test tools on the host using a higher-level interpreted programming language, to better organize the test cases and easily integrate the parsing of test results using regular expressions. Python, Perl, Ruby, and other languages with similar characteristics, are often a good fit for this purpose, also thanks to the availability of libraries and components designed for collecting and analyzing test results and interacting with continuous integration engines. A good organization of the test and verification infrastructure contributes more than everything else to the stability of the project, because regressions can be detected at the right time only if all the existing tests are repeated at every modification. Constantly running all the test cases while the development is ongoing not only improves the efficiency of detecting undesired effects as early as possible, but helps keep the development goals visible at all times, by directly measuring the number of failures, and makes the refactoring of components more affordable at any stage in the project lifetime.

Efficiency is the key, because embedded programming is an iterative process with a number of steps being repeated over and over, and the approach required from the developers is much more predictive than reactive.

主站蜘蛛池模板: 莱阳市| 闻喜县| 二连浩特市| 平舆县| 托克逊县| 庆阳市| 文安县| 沙田区| 镇沅| 凤城市| 原平市| 乌苏市| 汝阳县| 阿拉尔市| 卫辉市| 昌平区| 新乐市| 宿松县| 甘孜| 藁城市| 枝江市| 郎溪县| 客服| 灵山县| 四子王旗| 南投县| 永德县| 渝中区| 全南县| 兖州市| 广宁县| 库尔勒市| 黔西| 康平县| 马公市| 西青区| 东台市| 宣城市| 高尔夫| 白玉县| 弥勒县|