Post History
"How do I test" tends to be the wrong question, since the immediate follow-up question to that is always "what are your requirements?". It can't really be answered without knowing the requirements....
#2: Post edited
- "How do I test" tends to be the wrong question, since the immediate follow-up question to that is always "what are your requirements?". It can't really be answered without knowing the requirements.
- ---
- Regarding testing in general:
- Tests are often divided in two categories: black box testing vs white box testing. Black box testing is external tests that treats the DUT as a whole unit and tests how it fulfills things like environment requirements, EMC and so on. Whereas "white box"/"unit" testing tests internal components of the DUT separately, one at a time, to see if they function as expected. You need both kinds of tests and some black box testing could also be left behind after development in the form of production tests.
- And naturally you would preferably have ways to test the hardware as well as the software. Designing the hardware with testing in mind is recommended, especially for advanced products. You might need to add test points for pogo pin test rigs etc. I know you are specifically asking about firmware, but on embedded systems hardware and software go hand in hand. If you for example expect 5V idle voltage on the UART pins and test this in a test rig and get 0V, is the problem bad soldering, a broken IC or some firmware bug? It could be any of these and as far as the test goes, the cause doesn't matter, as long as the fault is caught.
- The most important thing about any embedded testing in general is that it ought to be carried out on the specific hardware. Partially because of the MCU ISA which is very different from some generic PC, partially because there is always hardware present which is highly relevant to the test. This means that embedded firmware _cannot_ be meaningfully unit tested without the given hardware and therefore various "test suites" from the PC world are more or less utter garbage, to be instantly dismissed.
- One way to go about "white box" testing is the buzzword "TDD" (Test-driven Development") where you write unit tests for the firmware at the same time as you write the firmware. That is, the tests are integrated in the driver source and activated/deactivated with some `#define` switch.
- The main advantages of TDD is that the firmware gets written so that it is easily testable, and that you write the tests at the same time as you have everything about the unit still fresh in mind. Disadvantages is that it clutters down the code and can add artificial limits to the product such as increased need for memory or timing.
In safety-related products, the general rule is that no code which isn't actually executed in the live product must be present. So TDD with the tests integrated in the source is unacceptable.- One may then keep the tests entirely separated from the firmware and personally I like to handle that through version control. I create a separate "test repo" which is different from the normal firmware repo, but contains a copy of the source. It can still be TDD but you keep the sources separated.
- In safety-critical firmware, there is an ideal design like this:
- - All source code in the project must exist to fulfill a specific project requirement.
- - There may exist no source code in the project which cannot be traced to a requirement.
- - All tests must exist to see if the specific piece of firmware fulfills the requirement it was written to fulfill.
- This means that the requirement specification, the source code and the tests get directly connected to each other and all of them may need to be continuously updated during development. For example if there is a need code for which no requirement exists, then perhaps the specification needs an update. If you come up with a great stress test, then maybe that one should be mentioned in the requirements as something that the DUT must handle and if it doesn't, then maybe the firmware needs an update too.
- For non-critical firmware the above is utopia and rarely something you manage 100%, but it could be the goal to strive towards. In particular it is important that the specification remains a live document, or otherwise it might turn outdated or partially obsolete as the product is developed.
- The classic mistake is that there is one person in charge of the specification, typically a project manager (who may not even be an engineer!) who writes it all down in the beginning of the project and then the specification just sits there statically like some dead weight document. In reality there are always details which you only find out when you start to implement the product and the requirements likely need to be updated accordingly. (And that's without even mentioning confused customers causing significant requirements creep.)
- Another similar classic mistake is to develop the whole product then dump it on some test engineer who is then expected to come up with some sensible tests. That's just wrong - testing ought to have been considered much earlier and so the job of the test engineer shouldn't be to come up with tests, but rather to question if the tests that the developer has proposed are sound, to flesh them out further and then carry them out. Also, if it is impossible for the test engineer to do nothing but black box testing, then how do we know if appropriate white box testing was even carried out? Typically there is always some white box testing done during development, but it is not necessarily documented anywhere. I can drop way too many RL anecdotes about this, it is something that goes wrong very often.
- There's research indicating that the most common errors in safety-related firmware isn't plain bugs, but failure to adapt the product to the intended environment. That is: incomplete requirements missing out use-cases or environmental considerations. And this would be why good engineers are those who are potty-trained all the way from back in school to always think outside the box, to always question the specification. And the contrary: those who just do as they are told without any critical thinking are not true engineers.
- ---
- Now for your specific project, in order to come up with sensible tests, you always have to start with the _requirements_. Set the requirements and then make tests for them. Some relevant ones for UART might be:
- - Baudrate accuracy tolerance. How much may the project deviate from the specified baud rate?
- - Real-time throughput. How often does data arrive and how much data over time is the DUT supposed to handle?
- - UART overflow and framing error situations. How should the DUT handle these? There are lots of nasty test cases you can apply here, like feeding the UART a plain square wave with the same baud rated as the DUT. Or force-feed the DUT repeated data as rapidly as possible.
- - Data corruption on UART protocols. What is acceptable in terms of 1-bit errors, 2-bit errors, burst errors?
- (You can write a simulator on the PC injecting such errors into the packets, at least as far as the payload is concerned. But in the real world, bit errors may as well also hit the start/stop bits.)
- - Grounding. How exactly is the signal ground integrated and where is it connected to supply and/or chassis grounds? What will happen if it goes missing? What happens if we inject noise on the shield/chassis? Things like that.
- - EMC. You'll have external requirements from some standard about EMC (susceptibility and radiated) and these will dictate how the UART signals need to be designed. Do you need hardware filtering, differential signals (RS485), shielded cables, ESD protection etc etc.
- "How do I test" tends to be the wrong question, since the immediate follow-up question to that is always "what are your requirements?". It can't really be answered without knowing the requirements.
- ---
- Regarding testing in general:
- Tests are often divided in two categories: black box testing vs white box testing. Black box testing is external tests that treats the DUT as a whole unit and tests how it fulfills things like environment requirements, EMC and so on. Whereas "white box"/"unit" testing tests internal components of the DUT separately, one at a time, to see if they function as expected. You need both kinds of tests and some black box testing could also be left behind after development in the form of production tests.
- And naturally you would preferably have ways to test the hardware as well as the software. Designing the hardware with testing in mind is recommended, especially for advanced products. You might need to add test points for pogo pin test rigs etc. I know you are specifically asking about firmware, but on embedded systems hardware and software go hand in hand. If you for example expect 5V idle voltage on the UART pins and test this in a test rig and get 0V, is the problem bad soldering, a broken IC or some firmware bug? It could be any of these and as far as the test goes, the cause doesn't matter, as long as the fault is caught.
- The most important thing about any embedded testing in general is that it ought to be carried out on the specific hardware. Partially because of the MCU ISA which is very different from some generic PC, partially because there is always hardware present which is highly relevant to the test. This means that embedded firmware _cannot_ be meaningfully unit tested without the given hardware and therefore various "test suites" from the PC world are more or less utter garbage, to be instantly dismissed.
- One way to go about "white box" testing is the buzzword "TDD" (Test-driven Development") where you write unit tests for the firmware at the same time as you write the firmware. That is, the tests are integrated in the driver source and activated/deactivated with some `#define` switch.
- The main advantages of TDD is that the firmware gets written so that it is easily testable, and that you write the tests at the same time as you have everything about the unit still fresh in mind. Disadvantages is that it clutters down the code and can add artificial limits to the product such as increased need for memory or timing.
- In safety-related products, the general rule is that no code which isn't actually executed in the live product is allowed to be present. So TDD with the tests integrated in the source is unacceptable.
- One may then keep the tests entirely separated from the firmware and personally I like to handle that through version control. I create a separate "test repo" which is different from the normal firmware repo, but contains a copy of the source. It can still be TDD but you keep the sources separated.
- In safety-critical firmware, there is an ideal design like this:
- - All source code in the project must exist to fulfill a specific project requirement.
- - There may exist no source code in the project which cannot be traced to a requirement.
- - All tests must exist to see if the specific piece of firmware fulfills the requirement it was written to fulfill.
- This means that the requirement specification, the source code and the tests get directly connected to each other and all of them may need to be continuously updated during development. For example if there is a need code for which no requirement exists, then perhaps the specification needs an update. If you come up with a great stress test, then maybe that one should be mentioned in the requirements as something that the DUT must handle and if it doesn't, then maybe the firmware needs an update too.
- For non-critical firmware the above is utopia and rarely something you manage 100%, but it could be the goal to strive towards. In particular it is important that the specification remains a live document, or otherwise it might turn outdated or partially obsolete as the product is developed.
- The classic mistake is that there is one person in charge of the specification, typically a project manager (who may not even be an engineer!) who writes it all down in the beginning of the project and then the specification just sits there statically like some dead weight document. In reality there are always details which you only find out when you start to implement the product and the requirements likely need to be updated accordingly. (And that's without even mentioning confused customers causing significant requirements creep.)
- Another similar classic mistake is to develop the whole product then dump it on some test engineer who is then expected to come up with some sensible tests. That's just wrong - testing ought to have been considered much earlier and so the job of the test engineer shouldn't be to come up with tests, but rather to question if the tests that the developer has proposed are sound, to flesh them out further and then carry them out. Also, if it is impossible for the test engineer to do nothing but black box testing, then how do we know if appropriate white box testing was even carried out? Typically there is always some white box testing done during development, but it is not necessarily documented anywhere. I can drop way too many RL anecdotes about this, it is something that goes wrong very often.
- There's research indicating that the most common errors in safety-related firmware isn't plain bugs, but failure to adapt the product to the intended environment. That is: incomplete requirements missing out use-cases or environmental considerations. And this would be why good engineers are those who are potty-trained all the way from back in school to always think outside the box, to always question the specification. And the contrary: those who just do as they are told without any critical thinking are not true engineers.
- ---
- Now for your specific project, in order to come up with sensible tests, you always have to start with the _requirements_. Set the requirements and then make tests for them. Some relevant ones for UART might be:
- - Baudrate accuracy tolerance. How much may the project deviate from the specified baud rate?
- - Real-time throughput. How often does data arrive and how much data over time is the DUT supposed to handle?
- - UART overflow and framing error situations. How should the DUT handle these? There are lots of nasty test cases you can apply here, like feeding the UART a plain square wave with the same baud rated as the DUT. Or force-feed the DUT repeated data as rapidly as possible.
- - Data corruption on UART protocols. What is acceptable in terms of 1-bit errors, 2-bit errors, burst errors?
- (You can write a simulator on the PC injecting such errors into the packets, at least as far as the payload is concerned. But in the real world, bit errors may as well also hit the start/stop bits.)
- - Grounding. How exactly is the signal ground integrated and where is it connected to supply and/or chassis grounds? What will happen if it goes missing? What happens if we inject noise on the shield/chassis? Things like that.
- - EMC. You'll have external requirements from some standard about EMC (susceptibility and radiated) and these will dictate how the UART signals need to be designed. Do you need hardware filtering, differential signals (RS485), shielded cables, ESD protection etc etc.
#1: Initial revision
"How do I test" tends to be the wrong question, since the immediate follow-up question to that is always "what are your requirements?". It can't really be answered without knowing the requirements. --- Regarding testing in general: Tests are often divided in two categories: black box testing vs white box testing. Black box testing is external tests that treats the DUT as a whole unit and tests how it fulfills things like environment requirements, EMC and so on. Whereas "white box"/"unit" testing tests internal components of the DUT separately, one at a time, to see if they function as expected. You need both kinds of tests and some black box testing could also be left behind after development in the form of production tests. And naturally you would preferably have ways to test the hardware as well as the software. Designing the hardware with testing in mind is recommended, especially for advanced products. You might need to add test points for pogo pin test rigs etc. I know you are specifically asking about firmware, but on embedded systems hardware and software go hand in hand. If you for example expect 5V idle voltage on the UART pins and test this in a test rig and get 0V, is the problem bad soldering, a broken IC or some firmware bug? It could be any of these and as far as the test goes, the cause doesn't matter, as long as the fault is caught. The most important thing about any embedded testing in general is that it ought to be carried out on the specific hardware. Partially because of the MCU ISA which is very different from some generic PC, partially because there is always hardware present which is highly relevant to the test. This means that embedded firmware _cannot_ be meaningfully unit tested without the given hardware and therefore various "test suites" from the PC world are more or less utter garbage, to be instantly dismissed. One way to go about "white box" testing is the buzzword "TDD" (Test-driven Development") where you write unit tests for the firmware at the same time as you write the firmware. That is, the tests are integrated in the driver source and activated/deactivated with some `#define` switch. The main advantages of TDD is that the firmware gets written so that it is easily testable, and that you write the tests at the same time as you have everything about the unit still fresh in mind. Disadvantages is that it clutters down the code and can add artificial limits to the product such as increased need for memory or timing. In safety-related products, the general rule is that no code which isn't actually executed in the live product must be present. So TDD with the tests integrated in the source is unacceptable. One may then keep the tests entirely separated from the firmware and personally I like to handle that through version control. I create a separate "test repo" which is different from the normal firmware repo, but contains a copy of the source. It can still be TDD but you keep the sources separated. In safety-critical firmware, there is an ideal design like this: - All source code in the project must exist to fulfill a specific project requirement. - There may exist no source code in the project which cannot be traced to a requirement. - All tests must exist to see if the specific piece of firmware fulfills the requirement it was written to fulfill. This means that the requirement specification, the source code and the tests get directly connected to each other and all of them may need to be continuously updated during development. For example if there is a need code for which no requirement exists, then perhaps the specification needs an update. If you come up with a great stress test, then maybe that one should be mentioned in the requirements as something that the DUT must handle and if it doesn't, then maybe the firmware needs an update too. For non-critical firmware the above is utopia and rarely something you manage 100%, but it could be the goal to strive towards. In particular it is important that the specification remains a live document, or otherwise it might turn outdated or partially obsolete as the product is developed. The classic mistake is that there is one person in charge of the specification, typically a project manager (who may not even be an engineer!) who writes it all down in the beginning of the project and then the specification just sits there statically like some dead weight document. In reality there are always details which you only find out when you start to implement the product and the requirements likely need to be updated accordingly. (And that's without even mentioning confused customers causing significant requirements creep.) Another similar classic mistake is to develop the whole product then dump it on some test engineer who is then expected to come up with some sensible tests. That's just wrong - testing ought to have been considered much earlier and so the job of the test engineer shouldn't be to come up with tests, but rather to question if the tests that the developer has proposed are sound, to flesh them out further and then carry them out. Also, if it is impossible for the test engineer to do nothing but black box testing, then how do we know if appropriate white box testing was even carried out? Typically there is always some white box testing done during development, but it is not necessarily documented anywhere. I can drop way too many RL anecdotes about this, it is something that goes wrong very often. There's research indicating that the most common errors in safety-related firmware isn't plain bugs, but failure to adapt the product to the intended environment. That is: incomplete requirements missing out use-cases or environmental considerations. And this would be why good engineers are those who are potty-trained all the way from back in school to always think outside the box, to always question the specification. And the contrary: those who just do as they are told without any critical thinking are not true engineers. --- Now for your specific project, in order to come up with sensible tests, you always have to start with the _requirements_. Set the requirements and then make tests for them. Some relevant ones for UART might be: - Baudrate accuracy tolerance. How much may the project deviate from the specified baud rate? - Real-time throughput. How often does data arrive and how much data over time is the DUT supposed to handle? - UART overflow and framing error situations. How should the DUT handle these? There are lots of nasty test cases you can apply here, like feeding the UART a plain square wave with the same baud rated as the DUT. Or force-feed the DUT repeated data as rapidly as possible. - Data corruption on UART protocols. What is acceptable in terms of 1-bit errors, 2-bit errors, burst errors? (You can write a simulator on the PC injecting such errors into the packets, at least as far as the payload is concerned. But in the real world, bit errors may as well also hit the start/stop bits.) - Grounding. How exactly is the signal ground integrated and where is it connected to supply and/or chassis grounds? What will happen if it goes missing? What happens if we inject noise on the shield/chassis? Things like that. - EMC. You'll have external requirements from some standard about EMC (susceptibility and radiated) and these will dictate how the UART signals need to be designed. Do you need hardware filtering, differential signals (RS485), shielded cables, ESD protection etc etc.
