I'm not sure how this is different than TDD, but at the end it hits on a key point, something I've called "ROAC" (Runs On Any Computer):
"there was often a way to run the whole system, or a facsimile, on your laptop with minimal friction"
Any time the code you're developing can't be run without some special magic computer (that you don't have right now), special magic database (that isn't available right now), special magic workload (production load, yeah...), I predict the outcome is going to be crappy one way or another.
I went on read more articles that were linked. Another idea was having a cluster that is very close to production to which teams can deploy PRs that need to be tested (if they are related).
We have decided not to use anything that can't run any any computer. It's really possible to have large scale systems ROAC, if you pay attention to avoid proprietary cloud tech lock-in.
Anything interesting and server-based usually depends on an entire complex data pipeline (one system for this if you’re lucky) and a dozen or more external systems with no great way to mock them that won’t itself be out-of-sync with reality often, anyway.
> There’s a cynical read of “shift left” that is “make people do more work but pay them the same.”
I haven't heard of this. I thought shifting left was the new hotness.
I was under the impression that finding and fix mistakes as soon as possible is considered best practice.
> Shifting Testing Left Is a Return of an Older, Better System
I don't really understand. I thought the "old way" was to wait until everything was done to check if it works, and the "new way" was to add tests for individual components as you go, making sure nothing breaks as new features are added.
>>I thought the "old way" was to wait until everything was done to check if it works, and the "new way" was to add tests for individual components as you go, making sure nothing breaks as new features are added.
Things tend to be more cyclical.
30 years ago, we did unit tests where we continually test individual components, then system tests were you test if your system works as a whole, then integration tests where you check how your system works with others. We had dedicated environments for these. And this was in the big-corporation, bog-standard, boring, commercial-off-the-shelf standard enterprise resource planning software. Yes, we had waterfall / predictive project management model, but I'm not sure where this notion comes in that before right now, this exciting brilliant moment in time, nobody in IT knew at all what they were doing and built entire bridges for years and waited to see if they'd collapse when the first car came :-)
Grumble grumble get off my lawn young kids etc etc :->
Exactly. When I started my job 20 years ago, our company was waterfall, and my then boss (in his 50s) told me - never rely on QA, it's your responsibility as a developer to make sure the code (and product) works.
I think he was right. Today, apparently, he would be left.
"Left" isn't a personal label (like it is in politics); In this context it refers to having useful tests earlier on the timeline (where time in the development workflow is on the X axis).
Even the original waterfall paper describes an iterative project management model with testing & revisions on the results, at multiple levels of the system.
And just to demonstrate the universality of the human condition... just yesterday I was having a rant about (a) everything being always underbudgeted because the cheapest quote usually wins, so everyone underquotes hoping the client changes their mind and the resulting variation(s) swing the needle into profitability, and (b) that there's also a tendency to create artificial urgency (unrealistic deadlines etc.) in order to try and extract greater productivity from your workers.
Hanlon's Razor would tend to discredit (b) but I've seen it in action too many times to fully accept this...
I'm currently delivering a couple of new appsec test tools into the business, and it's the Devs who are most vocal about shifting left and wanting early access to the tools.
I'm all in favour, particularly if people don't see it as an imposition!
Not in the systems I've worked in. I interpret "shifting left" as preferring unit tests to integration tests. In that world, a unit test that runs in the same env as the dev box running compiler and completes in 20 ms will allow much, much faster iteration than an integration test that has to spin up an EC2 instance, upload code, run a script, download results, etc
I'm confused by this idea that 'testing' is a single thing that you can 'shift'. Testing is part of each step of envisaging, specifying, designing, implementing, shipping, supporting, updating, maintaining (and I'm sure I've missed a few) a product.
obviously there's some amount of validation that happens at each step. The question is just how much you do when, and how that affects when issues get discovered.
It is very easy with microservices to create something that nobody can figure out how to start everything needed for a full system test on their development machine. This is one of the downsides of microservices and if you use them you should be mitigating this somehow. (I don't work in a microservices environment and I can think of a dozen options - I'm sure someone who does can think of more as well as tell me why some of my ideas don't work)
Huh, it has lot to do with Micro service. Now we have so many moving parts in form of micro services that dev, qa, UAT testing does not mean much because each team is different timeline for release and final solution will have same version all across is not guaranteed.
The author poses a very real and valid question but posits no solution and frames this as a binary.
The question is when to test.
There is benefit and tradeoff when you decide when and how to test your application. Sometimes you simply cannot test beforehand, such as when you are integrating with a live system with a cost of replicating the environment very very high due to this being a managed solution contract with a large cough IBM cough vendor. In these cases often the question is when to mock test. Then when to test. But this is still just how and when.
With a solo developer, it makes plenty of sense to write the feature then test it. Writing it may be the way to actually discover the behavior you want. With a team this can still be the case. In a larger team you can pass this to QA engineers to take these rapid prototypes and find the issues with them for a different type of developer to fix bugs in.
The reverse is the same. You can discover your feature behavior by experimenting with tests until the desired behavior is asserted to be occuring through things like type validation and object patching for instrumentation, or whatever profiling or debugging tools and test suites you like.
The hard answer is there is no one answer. Just like iterative development urges us to do our best to keep up by iterating on our features, we should iterate on our tests. Do not worship coverage, use it as a tool. Do not fear testing, it's just code afterall so you can actually make a full application that is just a series of tests (experiments) that run and if everything has passed, well you just wrote the same thing as a bunch of conditional checks in your library code.
Do what works for you, your team, the project you are on and where you are at. If youre struggling add some more tests. If you have so many tests failing you dont know what to do, write some more code and string your tests together with new functions. It gives a nice way to say ok, this is the next step of my iteration. Some like to start by testing some like to finish. I do both. Whatever you do, put love into it and if thats super sturdy prod code that has no tests and will never fail because you are the safest data handler in the world with the most flexible business logic in the world, go for it - but just remember if you someday later forget how things work and dont want to read documentation or experiment with the live system - you can always write tests to remind you how it works.
Tests are a form of documentation. They may not prove what you think they prove, but they document a fact about your code that is objective as determined by the code itself. This is a wonderful power, use it however you wish.
There really is no one answer, and you're so right that scale is one of the determining factors. Sophisticated tools like Signadot are designed to help dozens of developers use one high-accuracy shared cluster, but that makes no sense if your team is small enough to Slack 'hey I'm going to push my stuff to Staging, no one change anything' for your testing phase :)
I feel like this is a case of one of those "movements" that is just "Yes, under certain circumstances this might be a good idea; and under others, it won't be". Consider that tests are literally executable specifications of how the system or component should behave (a formulation I associate with Dan North, but I'm sure the idea is far from original). Now the question becomes "should you write a spec every time before you start implementation"? It seems obvious that the answer to that rather depends on how well you actually understand the problem space you're trying to solve.
And if all the work you're doing is well understood before you start, I suggest finding somewhere your manager you with the hard stuff.
> It seems obvious that the answer to that rather depends on how well you actually understand the problem space you're trying to solve.
An advocate for TDD (as in “red > green > refactor”) might say that writing the spec upfront is an excellent way to understand the problem space, or at least to help achieve that understanding.
At least when I’ve been fortunate enough to work on projects where such a TDD approach is possible, I’ve found that to be the case. I’ve also often found it harder to gain that understanding when testing lags development.
I'm interested in others' experiences with "shifting left": if you are in the process of, are currently doing, are thinking about whether you should, or have and decided to "shift right" again, do you mind sharing here?
I think the real problem is thinking we have found an alternative to waterfall. Despite lots of attempts everything is waterfall in some way. Sure we have added feedback loops, if requirements are wrong we can change them and all that - but in the end the phases exist for a reason.
Despite going all in on agile from day one of a new greenfield project, very high test coverage from TDDing everything, and a large suite of automated integration tests - we still have a month of QA gating the release process as bugs constantly sneak past all that process in a complex system. QA and automated tests look for different classes of problems.
It kind of does. If you need to run your build through QA, product, upper management and regulatory approval then sorry, no matter how many standups you have - you're waterfall.
If you need an approval on a pull request and some automated tests to pass to give you enough confidence to deploy then that part of your process is agile at least (even if, say, the way you get requirements is not).
I don't know what regulatory approval or standups have to do with waterfall, and I'm not sure what automated tests have to do with whether or not you are agile.
"Shift left" is a relatively hot, relatively new catchall bizterm that typically makes one visualize pushing a workload "upstream" from its current place in the flow. In this context, I think TDD is close to what it means.
> "Shift left" is a relatively hot, relatively new catchall bizterm that typically makes one visualize pushing a workload "upstream" from its current place in the flow.
I've been shifting left (and using those words) for over two decades. Nothing new here.
> In this context, I think TDD is close to what it means.
Nope. It's only close in that both have to do with testing.
TDD is you writing unit tests. Shifting left is about parallelizing someone else's work in the rest of the test pyramid. If QA can write their integration/system/contract/other tests as you're writing your code, you can have working tests for new features ideally as soon as the feature is runnable/testable instead of QA waiting to "see what the dev code does" to write against it.
Thank you, that helps clear things up. The original article takes a very long time to get to its points.
Like the first commenter in this thread, I’d never heard the term “shifting left” before. That’s surprising for a buzzword you say has been around for decades and is hot right now, but I guess there’s a first time for everything!
"there was often a way to run the whole system, or a facsimile, on your laptop with minimal friction"
Any time the code you're developing can't be run without some special magic computer (that you don't have right now), special magic database (that isn't available right now), special magic workload (production load, yeah...), I predict the outcome is going to be crappy one way or another.