For some context, almost exclusively I work on ground software, e.g. integration and test (I&T) and mission operations, mostly the former recently. We're nearing our delivery deadline for our completed flight model hardware, so since the summer we've been in the I&T phase, integrating various spacecraft subsystems and running test campaigns on the lab bench, out in the field, or in our vacuum chamber.
I lead the development of our (Python 3 and PyQt4 based) general "Ground Support Equipment" (GSE) software, which the engineers use to communicate with the spacecraft over both a physical/umbilical serial UART interface and through our radio. Getting back to the point of the question though, during this time the software side has been focused solely to get the job done, sometimes in regretfully ad hoc ways.
In some sense, working closely with the engineers building the spacecraft almost necessitates this, since as capabilities are added to the spacecraft, the GSE must be extended to accommodate those in the way of new command and telemetry abilities. Some examples of more significant additions made within the last 8 months or so include adding radio interface capabilities (in our case, sending data through a TNC for uplink and connecting to a chain of SDR software for downlink), allowing for more complex command abilities (and the requisite handling of telemetry data), and creating sequences of commands for use in hardware tests. The more mundane day-to-day work mostly involves adding new commands for the spacecraft and making telemetry easily visible/accessible to engineers.
Throughout all of this though, there's been a great deal of seat-of-the-pants/build-it-as-you-need-it style development, even during test campaigns, because things break, issues (both in the GSE software or on the spacecraft) arise and have to be troubleshooted, etc. And though from the start I desperately wanted to have a (software) test architecture (set up a Jenkins server and everything!), the time and the will to write tests was often not available. From the outset I tried to make the architecture of the application amenable to easy extension, but many of the engineers, at least to begin with, weren't familiar enough with Python to do so, though this has gotten better with time. When time permits, I refactor and redesign (or sometimes actually design something that started as a kludge) the back end, internals, and GUI portions. In some instances I was lucky enough to have previously designed something with enough foresight to make it easy. Sometimes not.
With all that said, the end of the hardware build and test phase is near, so we're at a transition point regarding our coding practices and standards. There's a lot of "dead time" between delivering the satellite to the launch provider and the actual launch, so we've waited on building much of our in-flight mission operations software until now. Because this is the actual mission-critical ground software, though, we're taking the design/construction/devops a lot more seriously. Just this weekend I set up a new server to host a Jenkins instance and future documentation. We'll be running unit tests, coverage checks, and a linter, and also have regular code reviews.
Most of the mission operations software design was finished long ago, but since we're using the GSE as a base, and assumptions/plans may have changed since then, there will definitely be further refactoring and design. I basically look at this software as our actual "production" code as compared to our internal design and test tooling.
I'm quite glad that we'll taking a more systemized approach now, not only because of the importance of the in-flight ground software, but also because we've recently expanded our ops development team and will have many more people simultaneously contributing. Our external reviewers will of course be happy as well.
I didn't intend to write a novel here, but wanted to share some insight from a less-common place, even if we're not in industry. In the three years I've worked on this project, I've learned a huge amount, and have gotten to experiment in small ways with different practices, but I know I still have a lot more to learn. I'd love to hear perspectives from within academia (where code quality is notoriously neglected) and in the aerospace industry, where the stakes require a more rigorous approach.