We build our software locally, on a developer’s machine, and we run the tests. The artifacts that are generated from our code at this point are disposable. Once a developer is happy that the tests are passing they commit their code to the source repository and the CI box takes over.
In my world, the CI box is the ultimate arbiter of truth. Once it has built and successfully tested an artifact we upload it to nexus so that we have a central copy of it. A copy of this is then deployed to the functional test environment where it is examined for flaws. One through functional testing we take the same file from nexus and put it in our integration test environment and from their it goes through UAT and pre-prod. If it passes all the tests and the user’s agree then we deploy it to production.
The key here is that we’re using the same artifact across all environments. We’re not rebuilding for specific environments because this introduces a huge risk. You really don’t want to be putting an untested war in production, even if the only change from the tested one was in a config file that lists a database connection string. Can you count the things that could go wrong?
Now, we automate as much of this as possible of course using tools from what’s now called DevOps and custom automation scripts. This means that there is no chance for human error (at least at that level) and that once a process is automated and tested it’ll work tirelessly forever without flaw. It’ll also work very rapidly.
In my current gig it takes us a couple of minutes to build our suite of software and about 20 minutes to run all the unit and integration tests. We have automated tests throughout each environment too — gherkin — to run smoke tests in Fun, and integration tests in Int. We haven’t automated UAT yet, and I don’t think that we will — it’s just too useful to watch humans break things.
If your process is vastly different from this then you might have problems that you haven’t thought about. Propagation of tested artifacts through test environments is a core principle of software engineering and if you aren’t doing it then you’re missing out.