How to write unit tests for embedded C code?

I have inherited a project with xxxx number of lines of C code to be assembled and executed on a PIC microcontroller. As you might expect, once I did this nothing happened and I am left swinging in the wind about what went wrong.

Although I might be able to fix this using the MPLAB ICD debugger, I am convinced that writing unit tests for the code will highlight any bug(s) in the code and is a better long-term solution for a) bugfixes, b) feature updates, c) when developing new products.

The only problem is, I am unsure in what environment these unit tests should be written in.

Does anyone have any thoughts/hints/experience in: a) writing unit tests for C code? b) writing unit test for embedded systems?

Thanks,

Stephen.

Reply to
smo59
Loading thread data ...

It is probably problem with compiler, linker or some else settings maybe you should contact the person that left that project and ask for begining instructions.

I think writing test units would be as big of a job as writing an application itself, it is good for big projects that many coders are involved in.

There is a lot of information on the subject on the Net, go to google and search for it.

Mickey

swinging

should

Reply to
Mickey

Start at the very beginning, and make sure the hardware works, the clock oscillates etc. Write a minimal program, no interrupts, just loops and wiggles a pin that you can see with a scope. Once that is working, you've got your compiler settings right, so work on a bit at a time, checking that the various bitsypieces hung on the IO behave as expected.

Then start with the project code. Put probes in the code if possible, to output a serial mesage you can read, or wiggle a spare IO pin, when it gets to some particular point. For example, put in a tight pin wiggling loop just after the interrupts get enabled- if it keeps going, at least the interrupts aren't crashing the system. Put a wiggle in the time interrupt, and see that it's going, and at the expected rate. Treat the other interrupt routines the same, one at a time.

Paul Burke

Reply to
Paul Burke

Congratulations on being interested in writing unit tests. You are a rarity amoung engineers.

There are a couple of fairly simple approaches that you can use, both of which should accomplish what you want.

The idea is to treat code functions, whether high level or assembly language equivalents as units divorced from the finished product. The approach with the lower startup cost it to use additional C code to generate test routines that will call the function under test (FUT). A more sophisticated approach does essentially the same but with the use of a commercial test tool such as Cantata

formatting link

The most common difficulty in either case is separating the FUT from the other functions in the file (presuming you are not using one file per function). To test your function, you would call it from the test function and ideally have stubs written to replace any functions it calls.

The stubs should be able to report that they were called and be able to return a definable set of good/bad values that are expected by the FUT.

If you use printf or fprintf in your code and stubs, you can produce a test record that identifies what is being tested and that all the stubs were called in the correct sequence, with the correct values, etc.

These calls to the FUT are repeated with a range of the test values to determine how your function will respond. Use both good and bad values that represent a good range of potential inputs. Remember, the concept in testing is to attempt to prove the code does not work. Success by failure, so to say.

The advantage to this type of testing is that it does not necessarily need to be done on the target (PIC in your case). You can do all of this testing on a PC, divorced from the actual hardware. It is common to repeat the testing on the target, but this is not always possible/practical on smaller processors.

Of course this is all based on having some "decent" specifications for what the code is supposed to do.

Documentation is truly the key to testing.

--
Scott
Validated Software Corp.
Reply to
Not Really Me

I'm not sure that writing unit tests is the best solution for your situation. But take a look at MinUnit, "a minimal unit testing framework for C".

formatting link

-- Kevin

Reply to
Kevin Kramb

The actual environment can be kept simple often with little more than the normal development environment. The fundamental difference between embedded system environments and hosted test environments is C compilers for embedded systems generate optimized code that is quite different when small changes are made to the source code. Instrumentation in embedded applications are prone to generate very different code than the application when the instrumented is not included. ( Heisenbugs :) In many cases instrumented application code will not for various reasons run on the real application target.

At Byte Craft (we also make a C compiler for Microchip PIC's), we have worked with a high volume customers to develop technology designed for Unit Testing that runs on the same application code image that will ultimately be shipped. The two goals were a) eliminate the Heisenbugs in the testing process b) automate the process to reduce human error.

We made two changes in the compiler to support the test process. The first change was to create a messaging system so the compiler could communicate directly with the debug environments either a simulator or emulator. This messaging system does quite a few things

1) passes information that is embedded in the source program in the form of reports. It includes debugging setup information, identifies library and function information and links to test data so each of these can be tested in situ using the code and variable assignments compiled into the actual application code.

2) The compiler was modified to emit information about control flow. These are essentially the same kind of nodes that are used by McCabe and others to instrument sources for code coverage tests, the difference is again we are instrumenting the application without changing the application image. The node lists are used by the debug environment to track execution progress and obtain automated results from insitu unit tests.

Walter Banks

1 (519) 888 6911 snipped-for-privacy@bytecraft.com
formatting link

smo59 wrote:

Reply to
Walter Banks

Thank you everyone for your suggestions. I think in the short term, I will have to go back to basics to find the fault, but for the long term will try to integrate unit testing within the design process.

Thanks again.

Stephen.

normal

system

systems

made to

generate

included.

various

worked

Testing

shipped.

of

in

are

node

obtain

swinging

b)

should

Reply to
smo59

Along with a unit test coverage framework, you may also be interested a test coverage tool to help you assess how well tested your code is.

We offer test coverage tools that work with any ANSI C compiler, and have very low probe insertion overhead. See

formatting link

--
Ira D. Baxter, Ph.D., CTO   512-250-1018
Semantic Designs, Inc.      www.semdesigns.com







----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000
Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Reply to
Ira Baxter

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.