What features does production quality software have?

Hi,

I had been lurking the forum and blog posts and the last month What we’ve been reading in April post raised a question.

First some background about myself, I have an EE degree but enjoy software development more. I’ve been working for a couple of years, my workplace mostly did PCB assembly, once the clients required us to develop software for their project I started to get used to good software practices like:

  • Version control.
  • Develop software modules.
  • Understanding bugs and find the root cause before doing any change to the software.
  • Lastly I’m doing Unit testing with Unity and function faking/mocking with fff (with great help of the Test Driven Development for Embedded C of James W. Grenning and the electronvector.com site).

Now I find myself in a position where I want to pursue embedded software development in a bigger workplace, with focus on automotive software development. I’m not certain about what features must a software project have to consider it production quality?

I consider it need to have unit testing, static analysis, some sort of complexity measurement, docs, requirements and further ways of testing.

@francois helped me with the following list:

I think this really depends on your project & industry. In my opinion, the minimum viable project has a strong specification and a test plan.

Beyond that, I think the following technologies allow companies to ship quality faster, with less risk:

Revision control
Code Review
Automated Builds
Continuous Integration
Unit Testing
Integration Testing
Automated Releases

I personally insist of these practices being used on the projects I work on. There of course are others that go above and beyond the aforementioned: canary releases, feature flags, automated hardware-in-the-loop tests, automated fuzzing, error monitoring, … and more.

Hope that helps!

So my question is about what features/requirements do you think or know production quality software must have?
How to improve my development?

Regards

So my question is about what features/requirements do you think or know production quality software must have?

The topic is broad and the answer to the question is unique and different for every company/device. It’s an important one though, and it’s probably worth a blog post or two in itself honestly.

I think @francois gave some good direction into which items are important for developers of non-critical systems. There are likely more requirements for safety-critical systems, like automotive, such as fully redundant hardware which includes failover, MISRA coding standards, and many hours of testing.

In an effort to guide the conversation to where you find the most benefit, I think it might be worth flipping the question back to you @CarlosDiaz. What things do you think are next on your internal todo list, topics to learn next, and items to implement? The community can then provide inputs on whether those make sense.

Here’s an update on an oldie but a goodie… https://dev.to/checkgit/the-joel-test-20-years-later-1kjk

Although I still have my original objection to the original… Joel is/was a microsoft droid, so his “buying the best tools” bit is not good advice. It locks you into some vendor that doesn’t give a shit about your future.

Replace that with, “Pick the best of open source tools, pick a good LTS (long term support) distro (like ubuntu), and keep up to date.”

Spend your money on hardware and/or paying open source devs for support if you need it.

Other thing I would say is turn on high levels of compiler warnings and fail the build if there are any warnings. Keep the build clean, don’t just ignore warnings. Compilers are massively helpful these days. Things like valgrind and the compiler sanitizers are great tools too.

Hi @tyler, thanks for guiding the question.

After some time “developing” without unit testing I gave it a go and found the value it adds into the project, now always that I need to start a new software module I find myself thinking about ways of testing it, how to mock or fake the modules it interacts with and so on.

So my personal list of topics to lean next is:

  • Unit testing, getting familiar with both Unity and CppCheck (because they are open source), knowing the pros and cons of each one, getting more out of unit tests, right now I only test parsers, I would like to test state machines, communication protocols, etc.
  • Software design, design software modules without needing to “code” it.
  • Get more comfortable with git, get better practices with it.
  • Use the github/gitlab CI tools.

I was used to work with the IDE defaults, now I try to enable extra warnings, sometimes the vendor supplied code comes with several warnings I can’t get rid off. I should add valgrind into my todo list after I find an excuse to use it.

Beautiful :100:

@CarlosDiaz This sounds like a great list. A bit of each world, being code design, testing, and tooling.

I’ve splattered my thoughts and suggestions here in no coherent order:

Unit Testing:

  • Shameless plug: I just wrote an article, Unit Test Mocking, which may bring some more inspiration in what to (and how to) test. I find value in testing quite literally everything above register-poking drivers and anything that is more than a stub or pass-through layer.
  • Unity and CMock/fff will do everything you need. If it’s not done already, I suggest adding a way to the build system to run a single test instead of the full suite so that your iteration cycle is super quick.
  • Also, don’t forget that you have access to the host’s lldb/gdb for debugging unit tests!

SW Design:
Necessary, but how necessary depends on the size and scope of the project.

Git:

  • All for it. Git should never get in your way. When it stops getting in your way, then the learning is complete.
  • Since you originally asked for production quality code, the one strong piece of advice for using git is to add a section titled “Test Plan” to each and every git commit, especially if working on a team. The test plan should be detailed enough that the code reviewer can be confident that it was actually tested and the code will likely not fail.

CI: Can not be said enough how important this is. Reliable builds, unit tests on every commit, and being notified when the build breaks. Also, there’s nothing worse that building a broken release due to human error.

Adding a few more things I feel are necessary to write production quality firmware on a team:

  • Everyone needs to use the same tools, environment, and commands. This is where a cli comes in handy
  • Code reviews
  • Fault handling. When your device misbehaves, you have to know about it. Add fault handling to your code, logging, etc. If your device crashes and no one knows, it’s going to be a rough time.

Thanks for the suggestions on Unit Testing, I haven’t checked you last post but will. Using the gdb of my host machine was one of the “features” I showed to my colleagues.

I do feel comfortable using git, the everyday commands tho, once you get into some unusual commands I’m lost. Commit messages is where I need to get better, adding a Test Plan on it sounds like a good idea, I used to add a test demo on the PR when adding features.

I did setup a basic CI on a toy project, but I usually run the unit tests before pushing the commits into my remote, I guess running unit tests on the remote is to make sure the code is unit tested in case the programmer forgets about it?

I will need to read most of your blogs again :slight_smile:, I learn new things every time, even after reading a blog multiple times. The CLI must be really useful, even when working on personal open source projects, so contributors can use them.

Thanks for taking the time to reply.

Carlos

One advantage of CI is that (1) it always runs even if you forget, and (2) it runs on the vanilla code in your repository. Let me explain why (2) matters with some examples.

Let’s say you and a colleague both make changes that are incompatible with each other. Your local unit tests might pass, but CI will catch the issue when it runs tests post-merge on the master branch.

Another problem I sometimes run into is forgetting to add a file to my commit. My local tests pass (the file is in my local tree), but since I forgot to git add it the build is broken. CI will also catch this.

1 Like