Làm thế nào tôi có thể đơn vị kiểm tra mã Arduino?


185

Tôi muốn có thể kiểm tra đơn vị mã Arduino của tôi. Lý tưởng nhất là tôi có thể chạy bất kỳ bài kiểm tra nào mà không cần phải tải mã lên Arduino. Những công cụ hoặc thư viện có thể giúp tôi với điều này?

Có một trình giả lập Arduino đang được phát triển có thể hữu ích, nhưng dường như nó chưa sẵn sàng để sử dụng.

AVR Studio từ Atmel chứa một trình giả lập chip có thể hữu ích, nhưng tôi không thể thấy cách tôi sẽ sử dụng nó cùng với Arduino IDE.


Có một chủ đề khác về câu hỏi này từ năm 2011 tại arduino.cc/forum/index.php?action=printpage;topic=54356.0
Jakob

Cảm ơn @Jakob. Một trình giả lập Arduino được tham chiếu trong luồng đó (với các liên kết có khả năng hữu ích khác ở cuối trang): arduino.com.au/Simulator-for-Arduino.html
Matthew Murdoch

5
Thật không may, nó chỉ dành cho Windows, tôi muốn thấy một cách đơn giản để biên dịch và chạy mã Arduino từ dòng lệnh mà không có bất kỳ sự phụ thuộc vào nguồn hoặc phần cứng nào.
Jakob

3
Một bản cập nhật nhỏ, 5 năm sau: Simavr vẫn hoạt động rất nhiều và đã cải thiện rất nhiều kể từ khi câu hỏi được đặt ra, vì vậy tôi nghĩ rằng nó xứng đáng được đưa lên gần hơn. Và nó có thể là công cụ phù hợp để kiểm tra hồi quy, kiểm tra dựa trên kịch bản và tại sao không kiểm tra đơn vị. Bằng cách đó, mã bạn kiểm tra giống như mã trên phần cứng đích.
zmo

Đối với các dự án quan trọng, hãy xem xét một thử nghiệm phần cứng; MCU khác ngoài thời gian có thể và kiểm tra các phản ứng / chuyển đổi nút, thời gian khởi động, sử dụng tạm thời, v / ma, hoán vị tùy chọn kỳ lạ, v.v. Vâng, đó là phần cứng nhiều hơn để xây dựng, nhưng nó có thể thêm một lớp an toàn vào việc sửa đổi. rất nhiều thiết bị chuyên nghiệp sử dụng jtag et al.
dandavis

Câu trả lời:


136

Không chạy thử nghiệm đơn vị trên thiết bị Arduino hoặc Trình giả lập

Trường hợp chống lại các thiết bị vi điều khiển / Trình mô phỏng / Kiểm tra dựa trên Sim

Có rất nhiều cuộc thảo luận về ý nghĩa của bài kiểm tra đơn vị và tôi không thực sự cố gắng tranh luận về vấn đề đó ở đây. Bài đăng này không nói với bạn để tránh tất cả các thử nghiệm thực tế trên phần cứng mục tiêu cuối cùng của bạn. Tôi đang cố gắng đưa ra quan điểm về việc tối ưu hóa chu kỳ phản hồi phát triển của bạn bằng cách loại bỏ phần cứng mục tiêu khỏi các bài kiểm tra thường xuyên và thường xuyên nhất của bạn. Các đơn vị được thử nghiệm được giả định là nhỏ hơn nhiều so với toàn bộ dự án.

Mục đích của kiểm thử đơn vị là kiểm tra chất lượng mã của riêng bạn. Các bài kiểm tra đơn vị thường không bao giờ kiểm tra chức năng của các yếu tố ngoài tầm kiểm soát của bạn.

Hãy suy nghĩ về nó theo cách này: Ngay cả khi bạn đã kiểm tra chức năng của thư viện Arduino, phần cứng vi điều khiển hoặc trình giả lập, thì kết quả kiểm tra như vậy hoàn toàn không thể cho bạn biết bất cứ điều gì về chất lượng công việc của chính bạn. Do đó, việc viết các bài kiểm tra đơn vị không chạy trên thiết bị đích (hoặc trình giả lập) sẽ có giá trị và hiệu quả hơn nhiều.

Kiểm tra thường xuyên trên phần cứng mục tiêu của bạn có chu kỳ rất chậm:

  1. Tinh chỉnh mã của bạn
  2. Biên dịch và tải lên thiết bị Arduino
  3. Quan sát hành vi và đoán xem mã của bạn có đang làm những gì bạn mong đợi không
  4. Nói lại

Bước 3 đặc biệt khó chịu nếu bạn muốn nhận thông báo chẩn đoán qua cổng nối tiếp nhưng bản thân dự án của bạn cần sử dụng cổng nối tiếp phần cứng duy nhất của Arduino. Nếu bạn đã nghĩ rằng thư viện SoftwareSerial có thể giúp ích, bạn nên biết rằng làm như vậy có khả năng phá vỡ mọi chức năng yêu cầu thời gian chính xác như tạo ra các tín hiệu khác cùng một lúc. Vấn đề này đã xảy ra với tôi.

Một lần nữa, nếu bạn đã kiểm tra bản phác thảo của mình bằng trình giả lập và các thói quen quan trọng về thời gian của bạn chạy hoàn hảo cho đến khi bạn tải lên Arduino thực tế, thì bài học duy nhất bạn sẽ học là trình giả lập bị lỗi - và biết điều này vẫn còn không tiết lộ về chất lượng công việc của bạn

Nếu thật ngớ ngẩn khi thử nghiệm trên thiết bị hoặc trình giả lập, tôi nên làm gì?

Bạn có thể đang sử dụng máy tính để làm việc trong dự án Arduino của bạn. Máy tính đó là đơn đặt hàng có cường độ nhanh hơn vi điều khiển. Viết các bài kiểm tra để xây dựng và chạy trên máy tính của bạn .

Hãy nhớ rằng, hành vi của các thư viện Arduino và vi điều khiển nên được giả định là một trong hai đúng hoặc ít nhất là một cách nhất quán không chính xác .

Khi các thử nghiệm của bạn tạo ra đầu ra trái với mong đợi của bạn, thì bạn có thể có một lỗ hổng trong mã đã được thử nghiệm. Nếu đầu ra thử nghiệm của bạn phù hợp với mong đợi của bạn, nhưng chương trình không hoạt động chính xác khi bạn tải nó lên Arduino, thì bạn biết rằng các thử nghiệm của bạn dựa trên các giả định không chính xác và bạn có thể có một thử nghiệm sai sót. Trong cả hai trường hợp, bạn sẽ được cung cấp những hiểu biết thực sự về những thay đổi mã tiếp theo của bạn. Chất lượng phản hồi của bạn được cải thiện từ " một cái gì đó bị hỏng" thành " mã cụ thể này bị hỏng" .

Cách xây dựng và chạy thử nghiệm trên PC của bạn

Điều đầu tiên bạn cần làm là xác định mục tiêu thử nghiệm của bạn . Hãy suy nghĩ về những phần nào trong mã của riêng bạn mà bạn muốn kiểm tra và sau đó đảm bảo xây dựng chương trình của bạn theo cách mà bạn có thể cách ly các phần riêng biệt để kiểm tra.

Nếu các bộ phận mà bạn muốn kiểm tra gọi bất kỳ chức năng Arduino nào, bạn sẽ cần cung cấp các thay thế giả trong chương trình thử nghiệm của mình. Đây là công việc ít hơn nhiều so với nó có vẻ. Mock-up của bạn không thực sự phải làm bất cứ điều gì ngoài việc cung cấp đầu vào và đầu ra có thể dự đoán cho các thử nghiệm của bạn.

Bất kỳ mã nào của riêng bạn mà bạn định kiểm tra đều cần tồn tại trong các tệp nguồn khác với bản phác thảo .pde. Đừng lo lắng, bản phác thảo của bạn vẫn sẽ biên dịch ngay cả với một số mã nguồn bên ngoài bản phác thảo. Khi bạn thực sự hiểu được nó, ít hơn điểm nhập cảnh bình thường của chương trình của bạn sẽ được xác định trong tệp phác thảo.

Tất cả những gì còn lại là viết các bài kiểm tra thực tế và sau đó biên dịch nó bằng trình biên dịch C ++ yêu thích của bạn! Điều này có lẽ được minh họa tốt nhất với một ví dụ thế giới thực.

Một ví dụ làm việc thực tế

Một trong những dự án thú cưng của tôi được tìm thấy ở đây có một số thử nghiệm đơn giản chạy trên PC. Để gửi câu trả lời này, tôi sẽ xem xét cách tôi mô phỏng một số chức năng của thư viện Arduino và các bài kiểm tra tôi đã viết để kiểm tra các mô hình đó. Điều này không trái với những gì tôi đã nói trước đây về việc không kiểm tra mã của người khác bởi vì tôi là người đã viết các bản nhái. Tôi muốn rất chắc chắn rằng mock-up của tôi là chính xác.

Nguồn của mock_arduino.cpp, chứa mã trùng lặp một số chức năng hỗ trợ do thư viện Arduino cung cấp:

#include <sys/timeb.h>
#include "mock_arduino.h"

timeb t_start;
unsigned long millis() {
  timeb t_now;
  ftime(&t_now);
  return (t_now.time  - t_start.time) * 1000 + (t_now.millitm - t_start.millitm);
}

void delay( unsigned long ms ) {
  unsigned long start = millis();
  while(millis() - start < ms){}
}

void initialize_mock_arduino() {
  ftime(&t_start);
}

Tôi sử dụng mô phỏng sau để tạo đầu ra có thể đọc được khi mã của tôi ghi dữ liệu nhị phân vào thiết bị nối tiếp phần cứng.

fake_serial.h

#include <iostream>

class FakeSerial {
public:
  void begin(unsigned long);
  void end();
  size_t write(const unsigned char*, size_t);
};

extern FakeSerial Serial;

fake_serial.cpp

#include <cstring>
#include <iostream>
#include <iomanip>

#include "fake_serial.h"

void FakeSerial::begin(unsigned long speed) {
  return;
}

void FakeSerial::end() {
  return;
}

size_t FakeSerial::write( const unsigned char buf[], size_t size ) {
  using namespace std;
  ios_base::fmtflags oldFlags = cout.flags();
  streamsize oldPrec = cout.precision();
  char oldFill = cout.fill();

  cout << "Serial::write: ";
  cout << internal << setfill('0');

  for( unsigned int i = 0; i < size; i++ ){
    cout << setw(2) << hex << (unsigned int)buf[i] << " ";
  }
  cout << endl;

  cout.flags(oldFlags);
  cout.precision(oldPrec);
  cout.fill(oldFill);

  return size;
}

FakeSerial Serial;

và cuối cùng là chương trình thử nghiệm thực tế:

#include "mock_arduino.h"

using namespace std;

void millis_test() {
  unsigned long start = millis();
  cout << "millis() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    sleep(1);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void delay_test() {
  unsigned long start = millis();
  cout << "delay() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    delay(250);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void run_tests() {
  millis_test();
  delay_test();
}

int main(int argc, char **argv){
  initialize_mock_arduino();
  run_tests();
}

Bài đăng này đủ dài, vì vậy vui lòng tham khảo dự án của tôi trên GitHub để xem thêm một số trường hợp thử nghiệm đang hoạt động. Tôi giữ các công việc đang tiến hành của mình trong các ngành khác ngoài chủ, vì vậy cũng kiểm tra các nhánh đó để kiểm tra thêm.

Tôi đã chọn để viết các thói quen kiểm tra nhẹ của riêng mình, nhưng các khung kiểm tra đơn vị mạnh mẽ hơn như CppUnit cũng có sẵn.


1
Đây là một câu trả lời tuyệt vời! Cảm ơn bạn!
Jonathan Arkell

5
@WarrenMacEvoy Một lần nữa, tôi nghĩ rằng bạn đã thực hiện lời khuyên của mình và biến nó thành một thứ không phải. Bạn chắc chắn nên kiểm tra mã của mình trong môi trường thực tế TẠI MỘT SỐ ĐIỂM. Lập luận của tôi là bạn không nên làm điều đó mỗi ngày và bạn chắc chắn không nên gọi nó là một bài kiểm tra đơn vị.
Cứu tinh sắt

1
@to nướng_flakes Tôi không chắc bạn đã nhận được trích dẫn đó ở đâu, nhưng đó không phải là điều tôi đã nói. Các thử nghiệm đơn vị chạy trên thiết bị có rất nhiều vấn đề - vòng phản hồi rất chậm, bạn có thể không có bất kỳ cổng nối tiếp hoặc bất kỳ phương tiện IO nào khác để dự phòng trên thiết bị mục tiêu của mình và chúng có dung lượng rất hạn chế có thể ảnh hưởng đến phạm vi của bộ kiểm tra của bạn.
Cứu tinh sắt

1
@ChristianHujer Bạn chắc chắn nên kiểm tra trên phần cứng thực - không ai nói rằng bạn không bao giờ nên kiểm tra trên phần cứng đích. Bài viết của tôi là về việc thắt chặt chu kỳ phản hồi phát triển hàng ngày của bạn chặt chẽ bằng cách kiểm tra đơn vị trên máy phát triển của bạn. Chi phí thử nghiệm của bạn được giảm thiểu theo cách này vì bạn sẽ chỉ kiểm tra phần cứng mục tiêu của mình khi cần thiết.
Cứu tinh sắt

1
@Benjohn Các tệp nguồn phác thảo Arduino được sử dụng để có phần mở rộng "pde" mặc dù chúng là C ++. arduino.cc/en/Guide/En Môi # toc1
sắt

63

Trong trường hợp không có bất kỳ khung kiểm tra đơn vị nào có sẵn cho Arduino, tôi đã tạo ra ArduinoUnit . Đây là một bản phác thảo Arduino đơn giản thể hiện công dụng của nó:

#include <ArduinoUnit.h>

// Create test suite
TestSuite suite;

void setup() {
    Serial.begin(9600);    
}

// Create a test called 'addition' in the test suite
test(addition) {
    assertEquals(3, 1 + 2);
}

void loop() {
    // Run test suite, printing results to the serial port
    suite.run();
}

18
Các thử nghiệm dường như chỉ chạy trên arduino, vì vậy bạn không thể thực hiện chúng tự động trên máy phát triển của mình. Ý tưởng cơ bản của kiểm thử đơn vị là chạy chúng tự động, do đó thiết kế hiện tại dường như là một công cụ gỡ lỗi hơn nhưng không có khung kiểm thử đơn vị thực sự.
Jakob

1
Bạn đúng. Ngoài ra, để có thể chạy những thứ này trên PC, ngoài ra, cần phải có trình giả lập Arduino hoặc AVR. Không có lớp trừu tượng phần cứng thực sự trong các thư viện Arduino (vào lúc này) và các trình giả lập AVR khi tôi nhìn vẫn đang trong quá trình phát triển. Nếu mọi thứ đã chuyển sang bây giờ thì về nguyên tắc điều này có thể được thực hiện.
Matthew Murdoch

12
@MatthewMurdoch Tôi sợ rằng bạn không chính xác. Theo định nghĩa, kiểm tra đơn vị không bao giờ chạy trong môi trường đích. Trong thực tế, ý tưởng đằng sau thử nghiệm đơn vị là loại bỏ hoàn toàn môi trường mục tiêu khỏi thử nghiệm. Chúng luôn chạy trong môi trường giống như phòng thí nghiệm, chế nhạo tất cả các hoạt động bên ngoài của thiết bị đang được thử nghiệm để đảm bảo rằng thành công hay thất bại của thử nghiệm chỉ phản ánh trên thiết bị được thử nghiệm. Đó là một trong những lý do lớn nhất khiến mọi người sử dụng khái niệm Inversion of Control trong các dự án phức tạp.
Cứu tinh sắt

2
@ marcv81 Các khu vực tồn tại các vấn đề về tính di động như vậy rất có thể là đối tượng nghèo để thử nghiệm đơn vị. Hãy nhớ rằng các bài kiểm tra đơn vị chỉ nên kiểm tra mã CỦA BẠN, vì vậy hãy giới hạn phạm vi của chúng cho phù hợp. Với sự chênh lệch lớn về phần cứng mà chúng ta đang nói đến ở đây, tôi có thể chấp nhận rằng một số trường hợp như vậy có thể không thể tránh khỏi. Trong những trường hợp đó, một kỹ sư nên duy trì nhận thức và thực hiện các bước giảm nhẹ. Điều này có thể có nghĩa là thay đổi thiết kế của bạn để cải thiện khả năng kiểm tra hoặc thậm chí một cái gì đó đơn giản như chỉ ghi lại các sự kiện có liên quan.
Cứu tinh sắt

2
@Iron Cứu một bài kiểm tra đơn vị kiểm tra mã của bạn, nhưng mã của bạn chạy ở đâu đó. Nếu bối cảnh đó là hoặc mô phỏng bối cảnh Arduino; sau đó ArdunoUnit sẽ giúp bạn viết bài kiểm tra đơn vị. Nếu bạn nhìn vào dự án ArduinoUnit, kiểm tra meta của khung sẽ tự động tải, chạy và xác minh kết quả kiểm tra trên mục tiêu đa nền tảng. Giống như bạn làm trên các mục tiêu đa nền tảng khác. Quan điểm của bạn là một cái cớ để không kiểm tra mã trong một môi trường nhúng trong đó tính chính xác quan trọng, nếu không thường xuyên hơn, so với các bối cảnh khác.
Warren MacEvoy

21

Tôi có đơn vị thành công đáng kể kiểm tra mã PIC của mình bằng cách trừu tượng hóa quyền truy cập phần cứng và chế nhạo nó trong các thử nghiệm của tôi.

Ví dụ: tôi trừu tượng PORTA với

#define SetPortA(v) {PORTA = v;}

Sau đó SetPortA có thể dễ dàng bị chế giễu, mà không cần thêm mã trên cao trong phiên bản PIC.

Khi sự trừu tượng hóa phần cứng đã được kiểm tra một thời gian, tôi sẽ sớm thấy rằng mã thường đi từ giàn kiểm tra đến PIC và hoạt động lần đầu tiên.

Cập nhật:

Tôi sử dụng một đường may #incoide cho mã đơn vị, # bao gồm mã đơn vị trong tệp C ++ cho thiết bị thử nghiệm và tệp C cho mã đích.

Như một ví dụ tôi muốn ghép bốn màn hình 7 phân đoạn, một cổng điều khiển các phân đoạn và một cổng thứ hai chọn màn hình. Các giao diện mã hiển thị với màn hình thông qua SetSegmentData(char)SetDisplay(char). Tôi có thể chế nhạo những thứ này trong giàn thử C ++ của mình và kiểm tra xem tôi có nhận được dữ liệu mà tôi mong đợi không. Đối với mục tiêu tôi sử dụng #defineđể tôi nhận được một nhiệm vụ trực tiếp mà không cần chi phí của một cuộc gọi chức năng

#define SetSegmentData(x) {PORTA = x;}

Về nguyên tắc, tôi có thể thấy cách tôi có thể sử dụng 'đường may' của bộ tiền xử lý để kiểm tra đơn vị. Tuy nhiên tôi không chắc làm thế nào tôi có thể làm điều này mà không cần trình giả lập để chạy thử nghiệm hoặc trình biên dịch tương thích avr-gcc xuất ra (trong trường hợp của tôi) nhị phân Windows ...
Matthew Murdoch

Cảm ơn các cập nhật. Bạn có thực hiện các bài kiểm tra đơn vị trên PIC hoặc trên PC của bạn không?
Matthew Murdoch

Các bài kiểm tra đơn vị được chạy trên máy Mac bằng Xcode. Để chạy chúng trên Pic có lẽ sẽ cần một trình giả lập nào đó. Tóm tắt nó để nó chạy trên Mac làm cho việc chuyển đổi bộ xử lý trở nên dễ dàng hơn
David Sykes

Môi trường Arduino sử dụng trình biên dịch avr-gcc có một số đặc điểm riêng có nghĩa là biên dịch với gcc (hoặc trình biên dịch C ++ khác) và chạy trên PC có thể không có nghĩa là mã cũng sẽ biên dịch trên avr-gcc.
Matthew Murdoch

Bạn đang nói về sự khác biệt nào? Có phải chúng là những thứ không thể được xử lý với một số chỉ thị tiền xử lý?
Joseph Lisee

15

Có vẻ như emulino sẽ làm công việc một cách hoàn hảo.

Emulino là trình giả lập cho nền tảng Arduino của Greg Hewgill. ( Nguồn )

Kho GitHub


12

simavr là một trình giả lập AVR sử dụng avr-gcc.

Nó đã hỗ trợ một vài bộ vi điều khiển ATTiny và ATMega, và - theo tác giả - thật dễ dàng để thêm một số chi tiết.

Trong các ví dụ nằm ở simduino, một trình giả lập Arduino. Nó hỗ trợ chạy bộ tải khởi động Arduino và có thể được lập trình với avrdude thông qua Socat (một Netcat đã được sửa đổi ).


9

Bạn có thể kiểm tra đơn vị bằng Python với dự án của tôi, PySimAVR . Arscons được sử dụng để xây dựng và simavr cho mô phỏng.

Thí dụ:

from pysimavr.sim import ArduinoSim    
def test_atmega88():
    mcu = 'atmega88'
    snippet = 'Serial.print("hello");'

    output = ArduinoSim(snippet=snippet, mcu=mcu, timespan=0.01).get_serial()
    assert output == 'hello'

Bắt đầu thử nghiệm:

$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok

6

Tôi không biết bất kỳ nền tảng nào có thể kiểm tra mã Arduino.

Tuy nhiên, có nền tảng Fritzing , bạn có thể sử dụng để mô hình hóa phần cứng và sau đó là xuất các sơ đồ và công cụ PCB.

Đáng để kiểm tra.


6

Chúng tôi đang sử dụng bảng Arduino để thu thập dữ liệu trong một thí nghiệm khoa học lớn. Sau đó, chúng tôi phải hỗ trợ một số bảng Arduino với các triển khai khác nhau. Tôi đã viết các tiện ích Python để tải động các hình ảnh hex Arduino trong quá trình thử nghiệm đơn vị. Mã được tìm thấy trong liên kết dưới đây hỗ trợ Windows và Mac OS X thông qua tệp cấu hình. Để tìm ra vị trí hình ảnh hex của bạn được đặt bởi Arduino IDE, hãy nhấn phím shift trước khi bạn nhấn nút build (play). Nhấn phím shift trong khi nhấn tải lên để tìm vị trí avrdude (tiện ích tải lên dòng lệnh) của bạn nằm trên hệ thống / phiên bản Arduino của bạn. Ngoài ra, bạn có thể xem các tệp cấu hình đi kèm và sử dụng vị trí cài đặt của bạn (hiện tại trên Arduino 0020).

http://github.com/toddstavish/Python-Arduino-Unit-Testing


+1 công cụ tuyệt vời! Bạn có bất kỳ thông tin nào về cách bạn đã kiểm tra đơn vị của mình sau khi hình ảnh được tải lên không?
Matthew Murdoch

Chúng tôi đã sử dụng nosetests để chạy thử nghiệm đơn vị của chúng tôi về phía con trăn. Thiết lập cho mỗi thử nghiệm tải hình ảnh hex chính xác cho thử nghiệm đó. Chúng tôi bắt đầu nhỏ và sau đó làm việc để kiểm tra toàn diện hơn. Đảm bảo giao tiếp nối tiếp đang hoạt động, đảm bảo tích hợp nối tiếp với UI đang hoạt động, kiểm tra nối tiếp với tích hợp DB, v.v ... pde và py tương tự hiển thị những điều cơ bản của điều này (xem liên kết github ở trên). Cuối cùng, chúng tôi sẽ mở nguồn toàn bộ dự án, vì vậy hãy theo dõi. :)
chập chững

6

Chương trình này cho phép tự động chạy một số bài kiểm tra đơn vị Arduino. Quá trình thử nghiệm được bắt đầu trên PC nhưng các thử nghiệm chạy trên phần cứng Arduino thực tế. Một bộ các bài kiểm tra đơn vị thường được sử dụng để kiểm tra một thư viện Arduino. (điều này

Diễn đàn Arduino: http://arduino.cc/forum/index.php?topic=140027.0

Trang dự án GitHub: http://jeroendoggen.github.com/Arduino-TestSuite

Trang trong Chỉ mục gói Python: http://pypi.python.org/pypi/arduino_testsuite

Các bài kiểm tra đơn vị được viết bằng "Thư viện kiểm tra đơn vị Arduino": http://code.google.com.vn/p/arduinounit

Các bước sau đây được thực hiện cho từng bộ kiểm tra đơn vị:

  • Đọc tệp cấu hình để tìm ra thử nghiệm nào để chạy
  • Kịch bản biên dịch và tải lên một bản phác thảo Arduino có chứa mã kiểm tra đơn vị.
  • Các bài kiểm tra đơn vị được chạy trên bảng Arduino.
  • Kết quả kiểm tra được in qua cổng nối tiếp và được phân tích bằng tập lệnh Python.
  • Kịch bản bắt đầu thử nghiệm tiếp theo, lặp lại các bước trên cho tất cả các thử nghiệm được yêu cầu trong tệp cấu hình.
  • Kịch bản in một bản tóm tắt cho thấy tổng quan về tất cả các bài kiểm tra thất bại / đã qua trong bài kiểm tra hoàn chỉnh.

5

Giữ mã riêng biệt cho phần cứng hoặc tách biệt với phần còn lại để bạn có thể kiểm tra và gỡ lỗi "phần còn lại" lớn hơn trên bất kỳ nền tảng nào mà bạn có các công cụ tốt và bạn quen thuộc nhất.

Về cơ bản, hãy cố gắng xây dựng càng nhiều mã cuối cùng từ càng nhiều khối xây dựng đã biết để làm việc càng tốt. Công việc cụ thể phần cứng còn lại sau đó sẽ dễ dàng hơn và nhanh hơn nhiều. Bạn có thể hoàn thành nó bằng cách sử dụng trình giả lập và / hoặc thiết bị mô phỏng hiện có của riêng bạn. Và sau đó, tất nhiên, bạn sẽ cần phải kiểm tra thực tế bằng cách nào đó. Tùy thuộc vào hoàn cảnh, điều đó có thể hoặc không thể tự động hóa tốt (nghĩa là ai hoặc cái gì sẽ nhấn nút và cung cấp các đầu vào khác? Ai hoặc cái gì sẽ quan sát và giải thích các chỉ số và đầu ra khác nhau?).



5

Tôi đang sử dụng Searduino khi viết mã Arduino. Searduino là một trình giả lập Arduino và môi trường phát triển (Makefiles, mã C ...) giúp dễ dàng hack trong C / C ++ bằng trình soạn thảo yêu thích của bạn. Bạn có thể nhập các bản phác thảo Arduino và chạy chúng trong trình giả lập.

Ảnh chụp màn hình của Searduino 0.8: http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 sẽ được phát hành và một video sẽ được ghi lại ngay khi các thử nghiệm kéo dài được thực hiện .... trong một hoặc hai ngày.

Thử nghiệm trên trình giả lập không được coi là thử nghiệm thực sự, nhưng chắc chắn nó đã giúp tôi rất nhiều trong việc tìm ra những sai lầm ngu ngốc / logic (quên làm pinMode(xx, OUTPUT), v.v.).

BTW: Tôi là một trong những người đang phát triển Searduino.


5

Tôi xây dựng arduino_cicho mục đích này. Mặc dù chỉ giới hạn trong việc kiểm tra các thư viện Arduino (và không phải là bản phác thảo độc lập), nhưng nó cho phép các bài kiểm tra đơn vị được chạy cục bộ hoặc trên hệ thống CI (như Travis CI hoặc Appveyor).

Hãy xem xét một thư viện rất đơn giản trong thư mục Thư viện Arduino của bạn, được gọi DoSomething, với do-something.cpp:

#include <Arduino.h>
#include "do-something.h"

int doSomething(void) {
  return 4;
};

Bạn sẽ kiểm tra đơn vị như sau (với một tệp kiểm tra được gọi test/is_four.cpphoặc một số như vậy):

#include <ArduinoUnitTests.h>
#include "../do-something.h"

unittest(library_does_something)
{
  assertEqual(4, doSomething());
}

unittest_main()  // this is a macro for main().  just go with it.

Đó là tất cả. Nếu assertEqualcú pháp và cấu trúc kiểm tra đó trông quen thuộc, thì đó là vì tôi đã sử dụng một số thư viện ArduinoUnit của Matthew Murdoch mà anh ấy đã đề cập trong câu trả lời của mình .

Xem Reference.md để biết thêm thông tin về các chân I / O thử nghiệm đơn vị, đồng hồ, cổng nối tiếp, v.v.

Các bài kiểm tra đơn vị này được biên dịch và chạy bằng cách sử dụng tập lệnh chứa trong viên ngọc ruby. Để biết ví dụ về cách thiết lập, hãy xem README.md hoặc chỉ sao chép từ một trong những ví dụ sau:


Điều này có vẻ thú vị, nhưng tôi không chắc rằng nó đang kiểm tra chính xác mã Arduino. Từ đầu ra bạn đã đăng, nó đang biên dịch sang kiến ​​trúc x86_64, rõ ràng là không được sử dụng cho Arduino. Điều đó có thể giới thiệu các lỗi gây ra bởi xung đột giữa các kiểu triển khai.
Cerin

Đó là loại lỗi chắc chắn có thể. Bạn có một ví dụ tôi có thể sử dụng cho một trường hợp thử nghiệm?
Ian

3

Có một dự án gọi là ncore , cung cấp lõi riêng cho Arduino. Và cho phép bạn viết các bài kiểm tra cho mã Arduino.

Từ mô tả dự án

Lõi riêng cho phép bạn biên dịch và chạy các bản phác thảo Arduino trên PC, nói chung không có sửa đổi. Nó cung cấp các phiên bản gốc của các chức năng Arduino tiêu chuẩn và một bộ điều khiển dòng lệnh để cung cấp đầu vào cho bản phác thảo của bạn thường xuất phát từ chính phần cứng.

Ngoài ra trên phần "tôi cần sử dụng cái gì"

Nếu bạn muốn xây dựng các bài kiểm tra, bạn sẽ cần cxxtest từ http://cxxtest.tigris.org . NCORE đã được thử nghiệm với cxxtest 3.10.1.


Đây là một dự án thú vị. Thật không may, có vẻ như nó đã chết, vì nó không có tiến triển trong 6 năm.
Cerin

2

Nếu bạn muốn kiểm tra mã đơn vị bên ngoài MCU (trên máy tính để bàn), hãy xem libcheck: https://libcheck.github.io/check/

Tôi đã sử dụng nó để kiểm tra mã nhúng của riêng tôi vài lần. Đó là khuôn khổ khá mạnh mẽ.


Nhược điểm duy nhất là điều này không hỗ trợ g ++, điều này khiến việc kiểm tra hầu hết các thư viện Arduino sử dụng các tính năng C ++ trở nên vô dụng.
Cerin

1

Bạn có thể sử dụng emulare - bạn có thể kéo và thả một vi điều khiển trên sơ đồ và chạy mã của bạn trong Eclipse. Các tài liệu trên trang web cho bạn biết làm thế nào để thiết lập nó.


1

Sử dụng Proteus VSM với thư viện Arduino để gỡ lỗi mã của bạn hoặc để kiểm tra nó.

Đó là một cách thực hành tốt nhất trước khi nhận mã của bạn trên tàu, nhưng hãy chắc chắn với thời gian vì mô phỏng không chạy thời gian thực khi chúng chạy trên bảng.


1

Hãy thử mô phỏng mạch Autodesk . Nó cho phép kiểm tra mã Arduino và mạch với nhiều thành phần phần cứng khác.


0

Trong Arduino cơ bản được viết bằng C và C ++, thậm chí các thư viện của arduino cũng được viết bằng C và C ++. Vì vậy, trong các thuật ngữ đơn giản, chỉ cần xử lý mã là C và C ++ và thử thực hiện kiểm tra đơn vị. Ở đây, bằng từ "xử lý", ý tôi là bạn thay đổi tất cả các cú pháp cơ bản như serial.println thành sysout, pinmode thành biến, vòng lặp void thành vòng lặp while () bị hỏng trong keystock hoặc sau một số lần lặp.

Tôi biết đây là một quá trình dài và không quá đơn giản. Theo kinh nghiệm cá nhân của tôi, một khi bạn đã làm được với nó, điều này sẽ trở nên đáng tin cậy hơn.

-Nandha_Frost


0

Trong trường hợp bạn quan tâm đến việc chạy một bản phác thảo INO và kiểm tra đầu ra nối tiếp, tôi có một triển khai làm việc đó trong dự án tổng kiểm tra Arduino NMEA của tôi .

Kịch bản sau đây lấy tệp và sử dụng Arduino CLI để biên dịch tệp thành tệp HEX sau đó được tải vào SimAVR để đánh giá tệp và in đầu ra nối tiếp. Vì tất cả các chương trình Arduino chạy mãi mãi mà không thực sự có tùy chọn tự chết ( exit(0)không hoạt động), tôi để bản phác thảo chạy trong vài giây và sau đó làm khác đầu ra bị bắt với đầu ra dự kiến.

Tải xuống và giải nén Arduino CLI (trong trường hợp này là phiên bản 0.5.0 - mới nhất tại thời điểm viết bài):

curl -L https://github.com/arduino/arduino-cli/releases/download/0.5.0/arduino-cli_0.5.0_Linux_64bit.tar.gz -o arduino-cli.tar.gz
tar -xvzf arduino-cli.tar.gz

Bây giờ bạn có thể cập nhật chỉ mục và cài đặt lõi thích hợp:

./arduino-cli core update-index
./arduino-cli core install arduino:avr

Giả sử bản phác thảo của bạn được đặt tên nmea-checksum.ino, để có ELF và HEX, hãy chạy:

./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino

Tiếp theo, SimAVR để chạy HEX (hoặc ELF) - Tôi xây dựng từ nguồn vì bản phát hành mới nhất không hoạt động với tôi:

sudo apt-get update
sudo apt-get install -y build-essential libelf-dev avr-libc gcc-avr freeglut3-dev libncurses5-dev pkg-config
git clone https://github.com/buserror/simavr.git
cd simavr
make

Biên dịch thành công sẽ cung cấp cho bạn simavr/run_avrnhững gì bạn có thể sử dụng để chạy bản phác thảo. Như tôi đã nói, timeoutnếu không nó sẽ không bao giờ chấm dứt:

cd simavr
timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true

Tệp được tạo sẽ có các ký tự điều khiển mã màu ANSI bao bọc đầu ra nối tiếp, để loại bỏ các ký tự đó:

cat nmea-checksum.ino.clog | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > nmea-checksum.ino.log
cat nmea-checksum.ino.log

Bây giờ tất cả những gì bạn cần làm là so sánh tệp này với một tệp tốt đã biết:

diff nmea-checksum.ino.log ../../nmea-checksum.ino.test

Nếu không có sự khác biệt, diffsẽ thoát với mã 0, nếu không tập lệnh sẽ thất bại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.