Ask HN: How do you keep track of software requirements and test them?
I'm a junior dev that recently joined a small team which doesn't seem to have much with regards to tracking requirements and how they're being tested, and I was wondering if anybody has recommendations.
Specifically, I would like to track what the requirements/specifications are, and how we'll test to make sure they're met? Which I don't know if this could be a mix of unit and integration/regression tests? Honestly though if this is maybe even the wrong track to take, I'd appreciate feedback on what we could be doing instead.
I used IBM Rational DOORS at a previous job and thought it really helped for this, but with a small team I don't think it's likely they'll spring for it. Are there open source options out there, or something else that's easy? I thought we could maybe keep track in a spreadsheet (this to match DOORS?) or some other file, but I'm sure there would be issues with that as we added to it. Thanks for any feedback!
133 comments
[ 3.8 ms ] story [ 114 ms ] threadI have never seen a requirements tracking software that worked well for large systems with lots of parts. Tracing tests to requirements and monitoring requirements coverage is hard. For projects of the size I work on I think more and more that writing a few scripts that work on some JSON files may be less effort and more useful than customizing commercial systems.
As an example, you could have a test that calls some public API and checks that you get the expected response. Assuming your requirement cares about the public API, or the functionality it provides.
I've tried to be as detailed as I can without knowing much about your application: assumptions were made, apply salt as needed.
Personally, I like having a test-suite be the documentation for what requirements exist. Removing or significantly modifying a test should always be a business decision. Your local Jira guru will probably disagree
I think the common answer is you don't use a requirements management tool, unless it's a massive system, with System Engineers who's whole job is to manage requirements.
Some combination of tech specs and tests are the closest you'll get. Going back to review the original tech spec (design doc, etc) of a feature is a good way to understand some of the requirements, but depending on the culture it may be out of date.
Good tests are a bit closer to living requirements. They can serve to document the expected behavior, and check the system for that behavior
[1] https://docs.gitlab.com/ee/user/project/requirements/
Whatever that feature is meant to be, it definitely isn't requirements management. Requirements don't stop being requirements after you've written the code.
2. Architecture and design docs explain the “how” to engineering.
3. The work gets broken down to stories and sub-tasks and added to a Scrum/Kanban board. I like Jira, but have also used Asana and Trello.
Testing is just another sub-task, and part of the general definition of some for a story. For larger projects, a project-specific test suite may be useful. Write failing tests. Once they all pass, you have an indication that the project is nearly done.
You can skip to #3 if everyone is aligned on the goals and how you’ll achieve them.
What sort of tests you want depends a lot on your system. If you're working on some data processing system where you can easily generate many examples of test input then you'll probably get lots of ROI from setting up lots of regression tests that cover loads of behaviour. If it's a complex system involving hardware or lots of clicking in the UI then it can be very good to invest in that setup but it can be expensive in time and cost. In that case, focus on edge or corner cases.
Then in terms of how you use it, you have a few options depending of the types of test:
- you can run through the tests manually every time you do a release (i.e. manual QA) - just make a copy of the spreadsheet and record the results as you go and BAM you have a test report
- if you have some automated tests like pytest going on, then you could use the mark decorator and tag your tests with the functional test ID(s) that they correspond to, and even generate a HTML report at the end with a pass/fail/skip for your requirements
I know it doesn't get much love on here, but a feature per requirement is a good level to start at. I'd recommend using `Examples` tables for testing each combination.
Having your features run on every PR is worth its weight in gold, and being able to deal with variations in branches relieves most of the headaches from having your requirements outside of the repo.
I like issue tracking that is central to code browsing/change request flows (e.g. Github Issues). These issues can then become code change requests to the requirements testing code, and then to the implementation code, then accepted and become part of the project. As products mature, product ownership folks must periodically review and prune existing requirements they no longer care about, and devs can then refactor as desired.
I don't like over-wrought methodologies built around external issue trackers. I don't like tests that are overly-concerned with implementation detail or don't have any clear connection to a requirement that product ownership actually cares about. "Can we remove this?" "Who knows, here's a test from 2012 that needs that, but no idea who uses it." "How's the sprint board looking?" "Everything is slipping like usual."
For a small team you can probably build a workable process in Microsoft Access. I use access to track my own requirements during the drafting stage.
For simple microservice-type projects I've found a .md file, or even mentioning the requirements in the main README.md to be sufficient.
I think it's important to track requirements over the lifetime of the project. Otherwise you'll find devs flip-flopping between different solutions. E.g. in a recent project we were using an open-source messaging system but it wasn't working for us so we moved to a cloud solution. I noted in the requirements that we wanted a reliable system, and cost and cloud-independence wasn't an important requirement. Otherwise, in two years if I'm gone and a new dev comes on board, they might ask "why are we using proprietary tools for this, why don't we use open source" and spend time refactoring it. Then two years later when they're gone a new dev comes along "this isn't working well, why aren't we using cloud native tools here"....
Also important to add things that aren't requirements, so that you can understand the tradeoffs made in the software. (In the above case, for example, cost wasn't a big factor, which will help future devs understand "why didn't they go for a cheaper solution?")
Also, if there's a bug, is it even a bug? How do you know if you don't know what the system is supposed to do in the first place?
Jira tickets describe individual changes to the system. That's fine for a brand new system. But after the system is 10 years old, you don't want to have to go through all the tickets to work out what the current desired state is.
However, what would be missing from this is discussions for each requirement specified. Or would you want to include that as well?
It would be nice having a dedicated directory for requirements, src, infra, tests and docs. Which would make things easier to track over long period of time I think
Top-level requirements are system requirements and each of them should be tested through system tests. This usually then drips through the implementation layers from system tests to integration tests, to unit tests.
Regression testing really is just running your test suite every time something changes in order to check that everything still works fine.
git to manage the graph, grep to search the graph, and run a Python http server in the directory if you want to share.
* https://github.com/doorstop-dev/doorstop * https://github.com/strictdoc-project/strictdoc
Of course requirements can be linked to test cases and test execution reports, based on a defined and described process.
How to build test cases is another story.
My opinion would be to not use all the fancy features that automatically tie issues to merge requests, releases, epics, pipelines etc... it's way to much for a small team that is not doing any type of management.
Just use some basic labels, like "bug" or "feature" and then use labels to denote where they are in the cycle such as "sprinted", "needs testing" etc. Can use the Boards feature if you want something nice to look at. Can even assign weights and estimates.
You can tie all the issues of a current sprint to a milestone, call the milestone a version or w/e and set a date. Now you have history of features/bugs worked on for a version.
In terms of testing, obviously automated tests are best and should just be a requirement built into every requirement. Some times though tests must be done manually, and in that case attach a word doc or use the comments feature on an issue for the "test plan".
* It seems like this would have been a milestone?
* So then maybe a few issues for the different classes or requirements?
* For each issue, after/during development I would note what tests are needed, maybe in the comments section of the issue? Maybe in the description?
* And then automated tests using junit?
Features cut across code, so no 1-1 mapping with classes. Tests are generally self-documenting and land alongside the feature they are for. You can document them, but likely either a comment in the issue/PR if technically interesting, or in a separate ~wiki doc as part of a broader specification.
Ideally each commit is valid & passes tests (see "conventional commits") and each issue/PR has accompanying tests whether around a new feature or bugfix. Particular test frameworks change every year.
If you have a requirement (doesn't matter how big or small) I'd treat that as 1 issue (regardless of how many java classes or lines of codes need modifying). If the issue is complex then within the issue's description you can use markdown (like checkboxes or bullet points) to identify subset requirements. However, if you can break that large requirement into functional changes that could exist/be deployed separately then I'd probably do multiple independent issues with some type of common identifier in the issue's name (or use your interpretation of milestones and put all those issues into 1).
If you use gitlab as your git repository then tying an issue to a merge request is easy and it would then show you the diff (aka all the changes to source code) that the issue required for implementation.
In terms of tests, same kind of answer - I don't know your rules. Every issue should have a test plan, perhaps using markdown in the issues description would convey that test plan the easiest. If you automate the test using junit then not sure the test plan is anything more than "make sure test xyz from junit passes", if it's a manual test then the issue's description can have a list of steps using markdown.
I really like end-to-end tests for this, because it tests the system from a user perspective, which is how many requirements are actually coming in, not how they are implemented internally. I also like to write tests for things that can't actually break indirectly. But it makes it so that someone who changes e.g. some function and thus breaks the test realizes that this is an explicit prior specification that they are about to invalidate and might want to double check with someone.
Your job is to do what is being asked of you and not screw it up too much.
If they wanted to track requirements, they'd already track them.
People have very fragile egos - if you come in as a junior dev and start suggesting shit - they will not like that.
If you come in as a senior dev and start suggesting shit, they'll not like it, unless your suggestion is 'how about I do your work for you on top of my work, while you get most or all of the credit'.
That is the only suggestion most other people are interested in.
Source: been working for a while.
However there is a spectrum, and if it turns from "listen rather than speak" in a respectful, learning sort of mentality to "shut up and do as I say, no questions", then requirements tools are not going to address the real problems.
In my experience, having requirements and processes and tools being used in a mindful way can be wonderful, but all that pales in comparison with the effectiveness of a well-working team. But that's the human factor and the difficult part.
Source: also been working a while. Seen good teams that were very democratic and also good teams that were very top-heavy militaristic (happy people all around in both scenarios).
So I _was_ trying to do only what was asked of me, just writing the code, but I guess I thought what I did at my previous job could have helped - which is keeping track of what was needed and then how I planned to accomplish and test.
But yeah, you've got me thinking about how or whether I should broach this topic; I think my lead is great, seems open to ideas, wants things to work well, so maybe I'll just ask what they think about how to avoid these kinds of mistakes.
This, 100%.
Don't tell anyone at work you asked on HackerNews and got feedback - they don't want to debate the merits of various approaches. They want it done their way, because it is obviously the right way, or else they would've modified it, right? :)
Most jobs are repetitive, so you eliminate mistakes just by doing it for a while. Hence nothing extra needs to be done, which is exactly how most people like it and why your company has no peer review or much of anything - because it just works, with the least amount of effort, somehow, someway :)
Changing internal processes without being a decision maker inside the company (e.g. an influencial manager/lead, the owner, a vp, etc.) is hard, even if there are clear benefits. If there of things that make no sense, there are no horizons for the improvements to come and you are not learning from your seniors, consider if it makes sense to move forward. Trying to change internal processes at reluctant employers is a common cause of immense frustration (and burnout), don't let yourself get caught into that.
TLDR adding structure isn’t always the answer. Your team/org needs to be open to that.
The PO has to make the hard decision about what to work on and when. He/She must understand the product deeply and be able to make the hard decisions. Also the PO should be able to test the system to accept the changes.
Furthermore. You don't really need to have endless lists of requirements. The most important thing to know is what is the next thing that you have to work on.
Moreover, if your PO can't define the goals, and what needs to be tested to get there, well you have a problem. Assuming the team is committed to some form of Agile and you have such a thing as a PO.
However, I also disagree with the main thrust of this comment. A PO should have responsibility, sure. But if that gets translated into an environment where junior devs on the team are expected to not know requirements, or be able to track them, then you no longer have a team. You have a group with overseers or minions.
There's a gray area between responsibility and democracy. Good luck navigating.
In some work environments, there may be unspoken requirements, or requirements that the people who want the work done don't know they have.
For example, in an online shopping business the head of marketing wants to be able to allocate a free gift to every customer's first order. That's a nice simple business requirement, clearly expressed and straight from the user's mouth.
But there are a bunch of other requirements:
* If the gift item is out of stock, it should not appear as a missing item on the shipping manifest
* If every other item is out of stock, we should not send a shipment with only the gift.
* If we miss the gift from their first order, we should include it in their second order.
* The weight of an order should not include the gift when calculating the shipping charge for the customer, but should include it when printing the shipping label.
* If the first order the customer places is for a backordered item, and the second order they place will arrive before their 'first' order, the gift should be removed from the 'first' order and added to the 'second' order, unless the development cost of that feature is greater than $3000 in which case never mind.
* The customer should not be charged for the gift.
* If the gift item is also available for paid purchase, orders with a mix of gift and paid items should behave sensibly with regard to all the features above.
* Everything above should hold true even if the gift scheme is ended between the customer checking out and their order being dispatched.
* The system should be secure, not allowing hackers to get multiple free gifts, or to get arbitrary items for free.
* The software involved in this should not add more than, say, half a second to the checkout process. Ideally a lot less than that.
Who is responsible for turning the head of marketing's broad requirement into that list of many more, much narrower requirements?
Depending on the organisation it could be a business analyst, a product owner, a project manager, an engineer as part of planning the work, an engineer as part of the implementation, or just YOLO into production and wait for the unspoken requirements to appear as bug reports.
That is just restating the problem that the "PO can't define the goals."
It's a bigger problem in the industry. Somehow, the Agile marketing campaign succeeded, and now everyone is Agile, regardless of whether the team is following one of the myriad paradigms.
I can rattle off dozens of orgs doing Scrum, but maybe 1 or 2 that actually are. Maybe doing two weeks of work and calling it a sprint, then doing another two weeks of work...and so on. No defined roles. It's just a badge word on the company's culture page.
The companies that are really doing something Agile are the consultancies that are selling an Agile process.
In my experience, engineer does it as part of implementation until they burn out and just YOLOs and leaves them for bug reports :p
But to be more serious, I don’t think this is POs or one persons job. This is exactly why engineers should learn about their domain.
Or maybe I just need to do better testing myself? There's no code reviews around here, or much of an emphasis on writing issues, or any emphasis on testing that I've noticed. So it's kind of tough figuring out what I can do
One I haven't seen mentioned yet - When Product is accountable & responsible for testing the outputs, they will understand the effort required and can therefore prioritize investment in testable systems and associated test automation.
When those aspects are punted over to architects/developers/QA, you'll end up in a constant battle between technical testing investments and new features.
But POs who are technical enough to understand the system to understand what the requirements of the system are, empirically, unicorns.
For requirement, use any kind of issue tracker and connect your commit with issues. Jira, people here hate it for various reason. But it get the job done. Otherwise GitHub issue would (there are problems with GitHub issues, e.g. cross repo issue tracking in a single place. That's another story)
For QA, you want your QA be part of the progress tracking and have it reflected in Jira/GitHub commit.
One thing I think is of equal importance, if not more, is how the code you delivered is used in the wild. Some sort of analytics.
Zoom out a bit, requirement is what you THINK the user want. QA is about whether your code CAN perform what you think the user want plus some safeguard. Analytics is how the user actually perform in real world
A bit off topic here, QA and analytics is really two side of the same coin. Yet people treat it as two different domains, two set of tools. On one hand, the requirement is verified manually through hand crafted test cases. On the other hand, production behavioural insight is not transformed into future dev/test cases effectively. It is still done manually, if any.
Think about how many time a user wander into a untested undefined interaction that escalated into a support ticket. I'm building a single tool to bridge the gap between product(requirement and production phase) and quality (testing)
[0] https://en.wikipedia.org/wiki/DO-178C
https://www.mindprod.com/jgloss/unmain.html
If builders built buildings the way programmers write programs, we’d have progressed from wattle-and-daub through wood and reinforced concrete to molecular nanotechnology construction in the first two generations of humans building occupied structures.
Bad analogy is bad because programs and buildings aren't remotely similar or comparable.
What we need is a practical way to keep the design and implementation synchronized and yet decoupled
Agile iteration is just as much about how you carve up work as how you decide what to do next. For example you could break up a task into cases it handles.
> WidgetX handles foobar in main case
> WidgetX handles foobar when exception case arises (More Foo, than Bar)
> WidgetX works like <expected> when zero WidgetY present
Those could be 3 separate iterations on the same software, fully tested and integrated individually, and accumulated over time. And the feedback loop could come internally as in "How does it function amongst all the other requirements?", "How is it contributing to problems achieving that goal?"
What you describe already occurs to some extent in the process and machinery safety sector, where specialised PLC programming languages are used - there is a type of graphical coding called Function Block, where each block can be a re-useable function encapsulated inside a block with connecting pins on the exterior. eg a two out of three voting scheme with degraded voting and MOS function available
The blocks are tested, or sometimes provided as a type of firmware by the PLC vendor, and then deployed in the overall program with expectation inside the block is known behavior, but before shipping, the entire program is tested at FAT.
Depending on the type of safety system you are building, and the hazards it protects against, there is potentially the expectation from the standards that every possible combination of inputs is tested, along with all foreseeable (and sometimes unexpected) mis-use of the machine/process.
In reality that's not physically achievable in any real time available for some systems, so you have to make educated guesses where the big/important problems might hide, fuzz etc, but the point is you aren't going to test like that until you think your system development is 100% complete and no more changes are expected.
And if you test and need to make any significant changes due to testing outcomes or emergent requirements, then you are potentially doing every single one of those tests again. At very least a relevant subset plus some randoms.
Background: I am registered TUV FS Eng and design/deliver safety systems.
It's a whole different game, across the multi year span of a project you might in some cases literally average less than one line of code a day, 95%+ of work is not writing code, just preparing to, and testing.
we have done this in quite a couple of companies where things like functional safety or other requirements had to be met. agile sadly gets a bad rep (as does devops) for the way it is rolled out in its grotesque perverted style in large orgs (wagile etc that are nothing but a promise to useless middle/line managers in large orgs not to fire them, or "dev(sec)ops" being condensed into a job title - if that is you, shoot your managers!).
if you increase test automation and get better visibility into risks already during the requirements management phase (e.g. probably you're doing D/FMEA already?) then nothing stops you from kicking these lazy-ass firmware hardware engineers who are scared of using version control or jenkins to up their game, and make your org truly "agile"). Obviously it's not a technical problem but a people problem (to paraphrase Gerald M. Weinstein) and so every swinging dick will moan about Agile not being right for them or DevOps not solving their issues, while in reality we (as an industry) are having the same discussion since the advent of eXtreme programming, and I'm so tired of it I want to punch every person who invites an Agile coach simply for not having the balls/eggs to say the things everyone already knows, it's infuriating to the point I want to just succumb to hard drugs.
This is exactly right. I work in a highly regulated space, and we have been working in an Agile framework for awhile now. There are two iterations baked into every release cycle (at the end) for final regression testing. That cycle will re-run every test case generated during the program increment, plus additional test cases chosen based on areas of the application that were touched during development.
On top of final validation, we also have an acceptance validation team that runs full integration tests after final validation is complete.
Can you refer me to any available online case studies etc, or provide me some more detail?
The sectors I work in we integrate off the shelf hardware such instruments, valves etc, we don't manufacture from components as such.
https://www.smharter.com/blog/safe-a-collection-of-comments-...
We largely used waterfall in GEOINT and I think it was a great match and our processes started to break down and fail when the government started to insist we embrace Agile methodologies to emulate commercial best practices. Software capabilities of ground processing systems are at least somewhat intrinsically coupled to the hardware capabilities of the sensor platforms, and those are known and planned years in advance and effectively immutable once a vehicle is in orbit. The algorithmic capabilities are largely dictated by physics, not by user feedback When user feedback is critical, i.e. UI components, by all means, be Agile. But if you're developing something like the control software for a thruster system, and the physical capabilities and limitations of the thruster system are known in advance and not subject to user feedback, use waterfall. You have hard requirements, so don't pretend you don't.
I don’t see why you can’t maintain the spirit of agile and develop iteratively while increasing fidelity, in order to learn out these things as early as possible.
The question is not whether you can't. The question is whether it provides advantages. Agile comes with its own downsides compared to a waterfall. Note, that I've been working with agile methods most of my career and I don't want to change that.
If working within a safety-critical industry and wanting to do Agile, typically you'll break down high-level requirements into sw requirements while you are developing, closing/formalizing the requirements just moments before freezing the code and technical file / design documentation.
It's a difficult thing to practice agile in such an industry, because it requires a lot of control over what the team is changing and working on, at all times, but it can be done with great benefits over waterfall as well.
I've always wanted to break that approach for something a little more nimble, probably by use of tools - but I can't see agile working in functional safety without some very specific tools to assist, which I am yet to see formulated and developed for anything at scale. Also, there are key milestones where you really need to have everything resolved before you start next phase, so maybe sprints, dunno.
The thing about doing waterfall/v-model is if done correctly there is little chance you get to the final Pre-Start Safety Review/FSA 3, or whatever you do before introducing the hazard consequences to humans, and a flaw is discovered that kicks you back 6 or 12 months in the design/validation/verification process. This, while everyone else stands around and waits because they are ready and their bits are good to go, and now you are holding them all up. Not a happy day if that occurs.
FS relies on high degree of traceability and testing the software as it will be used (as best possible), in it's entirety.
So not sure how agile could work in this context, or at least past the initial hazard and risk/requirements definition life cycle phases.
FS is one of things where your progress that you can claim is really only as far as your last lagging item in the engineering sequence of events. The standard expects you to close out certain phases before moving onto subsequent ones. In practice it's a lot messier than that unless extreme discipline is maintained.
(To give an idea of how messy it can get in reality, and how you got to try and find ways to meet the traceability expectations, sometimes in retrospect - last FS project I was responsible for design we were 2.5 years in and still waiting for the owner to issue us their safety requirements. We had to run on a guess and progress speculatively. Luckily we were 95%+ correct with our guesses when reconciled against what finally arrived for requirements)
But, normally racing ahead on some items is a little pointless and likely counterproductive, unless just prototyping a proof of concept system/architecture, or similar activity. You just end up repeating work and then you also have extra historical info floating around and there's possibility that some thing that was almost right but no longer current gets sucked into play etc etc etc. Doc control and revision control is always critical.
Background: I am a TUV certified FS Eng, I have designed/delivered multiple safety systems, mainly to IEC 61511 (process) or IEC 62061 (machinery).
I am about to do some automotive FS, so that is potentially ISO 26262, but it might actually be more 61508, which is the parent standard for the safety group of standards.
which sounds reckless, after all if you make a system more complicated by introducing a "feature" at least try to make it fail gracefully, etc, etc.
then you learn that this glorious safety critical software thing thing was fed by one single angle-of-attack measurement device (oh and to make the system even more mystical the planes had two of these digitalized wind detector flappy flaps, but only one was active, and it switched on reboots, so if one pilot noticed that the system was behaving badly, and then the second one noticed that it was great after all ... the third one had no clue what to expect!)
:|
Here's an excerpt from the article...
--- “No, again, we provide all the information that’s needed to safely fly our airplanes,” he answered.
Bartiromo pressed: But was that information available to the pilots? “Yeah, that’s part of the training manual, it’s an existing procedure,” Muilenburg said.
“Oh, I see,” she said. But in fact, MCAS wasn’t in the manual, unless you counted the glossary, which defined the term but didn’t explain what the software did. ---
A safety critical feature that can down a plane if not disabled in time... tucked away in a glossary.
The documentary 'Downfall: The Case Against Boeing' goes into great detail about the whole ordeal.
Another useful tool to use in conjunction to the above is running code coverage on each branch to ensure you don't have new code coming in that is not covered by unit tests.
Here are some options that I've seen in practice.
A: put everything in your repository in a structured way:
pros: - consistent - actually used in practice by the engineers
cons: - hard to work with for non-developers - too much detail for audits - hard to combine with documents / e-signatures
B: keep separate word documents
pros: - high level, readable documentation overview - works with auditor workflows - PM's can work with these documents as well
cons: - grows to be inconsistent with your actual detailed requirements - hard to put in a CI/CD pipeline
A whole different story is the level of details that you want to put in the requirements. Too much detail and developers feel powerless, too little detail and the QA people feel powerless.