You can't know what CI is unless you know what we used to do. Imagine a system with 3 parts. There's a UI that gathers data and puts it in the database. There's a reporting system that makes reports from the database. And there's some sort of server that monitors the database and sends email alerts if certain criteria are met.
Long ago this would be written as follows:
- Agree on the schema for the database and the requirements - this would take weeks because it had to be perfect as you'll soon see why
- Assign 3 devs, or 3 independent teams of devs, to the 3 pieces
- Each dev would work on their piece and test their piece using their own database copy, for weeks or months.
During this time the devs would not run each other's code, nor try to use a version of the database that had been created by someone else's code. The report writer would just hand add a bunch of sample data. The alert writer would hand add records that simulated report events. And the GUI writer would look at the database to see what the GUI had added. Over time, the devs would realize the spec was wrong in some way, such as not specifying an index or having too short a field length, and "fix" that in their version. They might tell the others, who might act on it, but usually these things would go on a list for later.
When all three parts were completely coded, and tested by their devs, and sometimes even tested by the users (showing them a report, a screen or an email alert) then would come the "integration" phase. This was often budgeted at several months but would still go over. That field length change by dev 1 would be discovered here, and would require devs 2 and 3 to make huge code changes and possibly UI changes too. That extra index would wreak its own havoc. And so on. If one of the devs was told by a user to add a field, and did, now would be the time the other two had to add it also.
This phase was brutally painful and pretty much impossible to predict. So people began to say "we have to integrate more often." "We have to work together from the beginning." "When one of us raises a change request [that's how we talked then] the others have to know about it." Some teams began to do integration tests earlier while continuing to work separately. And some teams began to use each other's code and output all the time, from the very beginning. And that became Continuous Integration.
You may think I am exaggerating that first story. I did some work for a company once where my contact chewed me out for checking in some code that suffered from the following flaws:
- a screen that he wasn't working on had a button that didn't do anything yet
- no user had signed off on the screen design (precise colours and fonts; the existence of the screen, its capabilities and what buttons it had were in the 300 page spec.)
It was his opinion that you don't put stuff into source control until it is DONE. He typically did one or two checkins a YEAR. We had a bit of a philosophy difference :-)
Also, if you find it hard to believe teams would be disconnected around a shared resource like a database, you really won't believe (but it's true) that the same approach was taken to code. You're going to write a function I can call? That's great, go ahead and do that, I will just hardcode what I need in the meantime. Months later I'll "integrate" my code so it calls your API and we'll discover it blows up if I pass null, I blow up if it returns null (and it does that a lot) it returns things that are too large for me, it can't handle leap years, and a thousand other things. Working independently and then having an integration phase was normal. Now it sounds like insanity.