-
Notifications
You must be signed in to change notification settings - Fork 4
serial.tutorial
The metal.serial
headers provide a set of macros, which will generate binary code that can be read on the host by metal.serial
. In order to use them we need to implement one function, write_metal_serial
that takes one byte and writes it to our communication channel. For our example we'll use std::putchar
to write the byte to stdout
.
void write_metal_serial(char c) {std::putchar(c);}
Now for the simplest example, we don't use any test macros, but only a printf and a exit-code tracker.
int main()
{
METAL_SERIAL_INIT(); //initalize communication
METAL_SERIAL_PRINTF("This message is generated from %s(%d).", STR(__FILE__), INT(__LINE__));
METAL_SERIAL_EXIT(42); //use 42 as the exit code
return 0;
}
The format string will not be read from the binary data, but directly from the source file (hence saving space), while the STR
and INT
tags tell the library in which format the data should be transmitted. metal.serial
uses boost.format
to implement the formatting. This allows us to use a formatting tool like printf
without using any heap.
This library is structured as a simplified form of metal.unit
, which will illustrate more of the test output.
Based on what we discussed in the prior section, we can now write a simple test:
int main()
{
METAL_SERIAL_INIT(); //initalize communication
METAL_SERIAL_ASSERT(true);
int x = 143;
METAL_SERIAL_EXPECT_EQUAL(12, x);
METAL_SERIAL_TEST_EXIT();
return 0;
}
Unlike metal.unit
, this library requires explicit mentions of initialization and exiting. This is because the binary needs to contain a sequence informing it about the initialization and exit of the test application.
The given test would then produce a binary, that if read by metal.serial
might produce output like this.
Initializing metal serial from test.cpp:9
test.cpp(10) assertion succeeded [true]: true
test.cpp(12) expectation failed [equality]: 12 == x; [12 == 143]
Exiting serial execution with 0
A test can be written directly into the main
function, but we also provide a solution to seperate test cases using METAL_CALL.
In hosted mode these entering and leaving test cases will be documented. This allows grouping tests and controlling the test flow.
The same tests
Tests not written inside cases are called free tests.
void test_cases_1()
{
METAL_SERIAL_ASSERT_EQUAL(42, 42);
}
void test_cases_2()
{
METAL_SERIAL_ASSERT_NOT_EQUAL(42, 42);
}
int main(int argc, char *argv[])
{
METAL_SERIAL_INIT();
METAL_SERIAL_EXPECT_EQUAL(42,0);
METAL_SERIAL_CALL(&test_cases_1, "Test Case 1");
METAL_SERIAL_CALL(&test_cases_2, "Test Case 2");
METAL_SERIAL_TEST_EXIT();
return 0;
}
Which would provide output like this.
Initializing metal serial from cases.cpp:15
cases.cpp(16) expectation failed [equality]: 42 == 0; [42 == 0]
cases.cpp(17) entering test case [Test Case 1]
cases.cpp(6) assertion succeeded [equality]: 42 == 42; [42 == 42]
leaving test case [Test Case 1]: { executed : 1, warnings : 0, errors : 0}
cases.cpp(18) entering test case [Test Case 2]
cases.cpp(11) assertion failed [equality]: 42 != 42; [42 != 42]
leaving test case [Test Case 1]: { executed : 1, warnings : 0, errors : 1}
free tests : { executed : 1, warnings : 1, errors : 0}
full test report: { executed : 2, warnings : 1, errors : 1}
Currently METAL_SERIAL_CALL only accepts function pointers with the signature void()
.
There are three ways to include the macros for the test.
Header | Language | Comment |
---|---|---|
<metal/serial.h> |
C | Macros in C style |
<metal/serial.hpp> |
C++ | Macros in C++ style |
- Overview
- Runner Introduction
- Runner Invocation
- Runner Plugins
- Runner Extender
- Runner FAQ
- Runner Reference
- Unit Introduction
- Unit Tutorial
- Unit FAQ
- Unit Reference
- Calltrace Introduction
- Calltrace Tutorial
- Calltrace FAQ
- Calltrace Plugin
- Calltrace Reference
- Serial Introduction
- Serial Tutorial
- Serial Invocation
- Serial Reference