단위 테스트 임베디드 소프트웨어
임베디드 시스템에 고유 한 임베디드 소프트웨어의 단위 테스트에 어떤 모범 사례를 사용 했습니까?
임베디드 소프트웨어는 지난 10 년 동안 먼 길을 걸어 왔지만 일반적으로 다음을 수행했습니다.
- 타겟 하드웨어에 의존하지 않는 알고리즘의 경우, 비 임베디드 플랫폼에서 빌드 및 테스트 된 단위 테스트 만있었습니다.
- 하드웨어를 필요로하는 것들의 경우, 유닛 테스트는 사용 가능한 모든 하드웨어를 사용하도록 조건부로 코드로 컴파일되었습니다. 우리의 경우에는 테스트의 정확성을 확인한 다른 더 유능한 시스템으로 결과를 푸시하는 대상의 직렬 포트였습니다.
- 하드웨어에 따라 내장되지 않은 플랫폼에서 "가상"장치를 더미 업할 수 있습니다. 이것은 일반적으로 프로그램이 사용하는 메모리를 변경하는 다른 실행 스레드 (또는 신호 함수)를 갖는 것으로 구성됩니다. 메모리 매핑 된 I / O에는 유용하지만 IRQ에는 유용하지 않습니다.
- 일반적으로 메모리 제약으로 인해 한 번에 전체 코드의 작은 하위 집합 만 단위 테스트 할 수 있습니다.
- 시간에 민감한 것들을 테스트하기 위해 우리는 그렇지 않았습니다. 단순하고 단순합니다. 우리가 사용한 하드웨어 (8051 및 68302)는 너무 느리게 실행되면 항상 작동하지 않았습니다. 이런 종류의 디버깅은 처음에는 CRO (오실로스코프)와 (더 많은 돈이있을 때) ICE (인-서킷 에뮬레이터)로 수행해야했습니다.
마지막으로 한 이후 상황이 개선 되었기를 바랍니다. 나는 내 최악의 적에게 그 고통을 원하지 않을 것입니다.
PC 환경 (PC C 컴파일러로 코드를 컴파일하고 PC 단위 테스트 프레임 워크에서 코드를 실행)에서 단위 테스트를 수행하면 많은 것을 얻을 수 있습니다.
- 이것은 시작 코드, RAM 테스트, 하드웨어 드라이버를 포함한 하위 수준 코드 테스트에는 적용되지 않습니다. 더 직접적인 단위 테스트를 사용해야합니다.
- 임베디드 시스템의 컴파일러는 신뢰할 수 있어야하므로 컴파일러에 의해 생성 된 버그를 찾지 않아도됩니다.
- 코드는 하드웨어 추상화와 함께 계층화 된 아키텍처 여야합니다. PC 단위 테스트 프레임 워크를위한 하드웨어 드라이버 시뮬레이터를 작성해야 할 수도 있습니다.
- 항상 평범한 것보다는
stdint.h
같은 유형을 사용해야합니다 .uint16_t
unsigned int
우리는 이러한 규칙을 따랐고, PC 단위 테스트 프레임 워크에서 애플리케이션 계층 코드를 단위 테스트 한 후 제대로 작동한다는 확신을 가질 수 있다는 것을 발견했습니다.
PC 플랫폼에서 단위 테스트의 장점 :
- 단위 테스트 프레임 워크 추가로 인해 임베디드 플랫폼에서 ROM 공간이 부족한 문제에 직면하지 않습니다.
- 컴파일-링크-실행주기는 일반적으로 PC 플랫폼에서 더 빠르고 간단합니다 (그리고 잠재적으로 몇 분이 될 수있는 '쓰기 / 다운로드'단계를 피합니다).
- 진행 상황을 시각화하고 (일부 임베디드 응용 프로그램에는 제한된 I / O 주변 장치가 있음), 분석을 위해 입력 / 출력 데이터를 저장하고, 더 많은 시간이 소요되는 테스트를 실행할 수있는 더 많은 옵션이 있습니다.
- 임베디드 플랫폼에 사용할 수 없거나 적합하지 않은 즉시 사용 가능한 PC 기반 단위 테스트 프레임 워크를 사용할 수 있습니다.
임베디드 시스템은 광범위한 주제이지만 일반적으로 하드웨어와 소프트웨어를 결합한 특정 목적의 제품이라고 생각합시다. 내 임베디드 배경은 모든 임베디드 시스템의 일부에 불과한 휴대폰에서 나왔습니다. 추상적 인 측면에서 다음 사항을 약간 유지하려고 노력할 것입니다.
가능할 때마다 하드웨어 종속성을 추상화하십시오. 이렇게하면 모의 "하드웨어"에서 단위 테스트를 실행할 수 있으며 대상에서 테스트하기 더 어려운 다양한 희귀 / 예외 사례도 테스트 할 수 있습니다. 추상화 비용을 방지하기 위해 조건부 컴파일을 사용할 수 있습니다.
하드웨어에 가능한 한 의존하지 마십시오.
에뮬레이터 또는 교차 컴파일러 환경에서 실행되는 단위 테스트는 여전히 코드가 대상 하드웨어에서 작동한다고 보장하지 않습니다. 타겟에서도 테스트해야합니다. 가능한 한 빨리 대상에서 테스트하십시오.
James W. Grenning의 Embedded C 를 위한 Test Driven Development 를 확인해 보세요. 이 책은 2010 년 8 월에 출판 될 예정이지만 베타 책은 현재 The Pragmatic Bookshelf 에서 볼 수 있습니다 .
여기에 경험이없는 목소리이지만, 최근에 제가 생각하고있는 것입니다. 나에게 가장 좋은 접근 방식은
A) 타겟에 쓰기 전에 PC 환경에서 가능한 한 많은 하드웨어 독립적 애플리케이션 코드를 작성하고 동시에 단위 테스트를 작성하십시오 (먼저 PC에서이 작업을 수행하면 하드웨어 독립적 인 물건을 분리하십시오). 이렇게하면 선택한 단위 테스터를 사용한 다음, 실행 속도에 따라 RS-232 및 / 또는 오실로스코프 및 I / O 핀이 시간 종속 데이터를 신호하는 I / O 핀을 사용하여 구식 방식으로 하드웨어 종속 항목을 테스트 할 수 있습니다. .
B) 대상 하드웨어에 모두 작성하되, 단위 테스트를 실행하고 RS-232 또는 다른 수단을 통해 결과 (또는 결과를 분석 할 수있는 데이터)를 출력하는 단위 테스트 빌드를 조건부로 컴파일하는 make target을 갖습니다. 메모리가 많지 않으면 까다로울 수 있습니다.
2009 년 7 월 3 일 편집 하드웨어 종속 항목을 단위 테스트하는 방법에 대해 또 다른 생각을했습니다. 하드웨어 이벤트가 너무 빨리 발생하여 RS-232로 기록 할 수 없지만 I / O 핀 플래그가 예상대로 상승 및 하강하는지 확인하기 위해 수많은 오실로스코프 데이터를 수동으로 검사하고 싶지 않은 경우 PC를 사용할 수 있습니다. DIO가 통합 된 카드 (예 : National Instruments의 데이터 수집 카드 라인)를 사용하여 해당 신호의 타이밍을 자동으로 평가합니다. 그런 다음 현재 실행중인 단위 테스트와 동기화하기 위해 데이터 수집 카드를 제어하는 소프트웨어를 PC에 작성하기 만하면됩니다.
우리는 시뮬레이터를 사용하여 꽤 많은 하드웨어 종속 코드를 테스트하고 Keil의 시뮬레이터와 IDE를 사용합니다 (그들의 도구를 사용하는 제휴 관계가 아닙니다). 우리는 반응 할 것으로 예상되는 방식으로 '하드웨어'를 구동하는 시뮬레이터 스크립트를 작성하고 작업 코드를 꽤 안정적으로 테스트 할 수 있습니다. 물론 일부 테스트를 위해 하드웨어를 모델링하는 데 약간의 노력이 필요할 수 있지만 대부분의 경우 이것은 매우 잘 작동하며 사용 가능한 하드웨어 없이도 많은 작업을 수행 할 수 있습니다. 우리는 하드웨어에 액세스하기 전에 시뮬레이터에서 거의 완전한 시스템을 작동시킬 수 있었으며 실제 코드를 한 번 처리 할 수있는 문제가 거의 없었습니다.
복잡한 제어 시스템, 메모리 인터페이스, 맞춤형 SPI 구동 IC 및 모노 디스플레이에서도 안정적으로 작동하도록했습니다.
여기에는 많은 좋은 답변이 있습니다. 언급되지 않은 몇 가지 사항은 다음을 위해 진단 코드를 실행하는 것입니다.
-
HAL 이벤트 기록 (인터럽트, 버스 메시지 등)
-
리소스 (모든 활성 세마포어, 스레드 활동)를 추적 할 코드가 있습니다.
-
교착 상태, 라이브 록, 메모리 누수, 버퍼 오버플로 등을 감지하고 디버그하기 위해 힙 및 메모리 콘텐츠를 영구 저장소 (하드 디스크 또는 이와 동등한)에 복사하는 캡처 램 메커니즘이 있습니다.
작년에이 문제에 직면했을 때 저는 임베디드 플랫폼 자체에서 테스트하고 싶었습니다. 나는 라이브러리를 개발하고 있었고 RTOS 호출과 임베디드 플랫폼의 다른 기능을 사용하고있었습니다. 사용할 수있는 특정 항목이 없으므로 UnitTest ++ 코드를 내 목적에 맞게 조정했습니다. 저는 NetBurner 제품군 에서 프로그래밍하고 웹 서버가 내장되어 있기 때문에 고전적인 RED / GREEN 피드백을 제공하는 웹 기반 GUI 테스트 실행기를 작성하는 것이 매우 간단했습니다. 그것은 꽤 잘 밝혀졌다, 이제 단위 테스트가 훨씬 쉬워졌으며 코드가 실제 하드웨어에서 작동한다는 것을 알면 훨씬 더 자신감이 생겼습니다. 단위 테스트 프레임 워크를 사용하여 통합 테스트도 수행합니다. 처음에는 하드웨어를 조롱 / 스텁하고 테스트를 위해 인터페이스를 삽입합니다. 하지만 결국에는 실제 하드웨어를 실행하는 man-in-the-loop 테스트를 작성합니다. 하드웨어에 대해 배우고 임베디드 트랩에서 쉽게 복구 할 수있는 훨씬 더 간단한 방법으로 밝혀졌습니다. 모든 테스트가 AJAX 콜백에서 웹 서버로 실행되기 때문에 트랩은 수동으로 테스트를 호출 한 결과로만 발생하며 시스템은 트랩 후 몇 초 후에 항상 깨끗하게 다시 시작됩니다.
NetBurner는 쓰기 / 컴파일 / 다운로드 / 실행 테스트주기가 약 30 초가 될만큼 충분히 빠릅니다.
Lots of embedded processors are available on eval boards, so although you may not have your real i/o devices, often you can execute a good deal of your algorithms and logic on one of these kinds of things, often w/hardware debugging available via jtag. And 'unit' tests usually are more about your logic than your i/o anyway. Problem is usually getting your test artifacts back out of one of these environments.
Split the code between device-dependent & device-independent. The independent code can be unit-tested without too much pain. The dependent code will simply need to be hand-tested until you have a smooth communications interface.
If you're writing the communications interface, I'm sorry.
참고URL : https://stackoverflow.com/questions/1061652/unit-testing-embedded-software
'Programing' 카테고리의 다른 글
화면을 비트 맵으로 캡처 (0) | 2020.12.01 |
---|---|
MySQL 함수 내에서 오류를 발생시키는 방법 (0) | 2020.12.01 |
Linux 기반 (공유 호스팅) 웹 서버에 wkhtmltopdf를 설치하는 방법 (0) | 2020.12.01 |
푸시 된 태그가 git 원격에 있는지 확인 (0) | 2020.12.01 |
Android의 외부 저장소에 파일 쓰기 (0) | 2020.12.01 |