Category / Continuous Integration

Continuous Integration: A Mindset, part II February 16, 2012 at 20:00

I received a couple of excellent questions/concerns about CI in a comment from Roger that I will try to address.

“How about human testing/QA? If team or feature branches are used, the QA department has a chance testing PBIs isolated before integrating with mainline which, hopefully, leads to more stable mainline.”

Ideally the QA department should not concern itself with testing in the traditional sense. The roll of the QA department, in my point of view, is to support the development teams by improving on the testing tools, maintain resources required to do automatic testing, help to improve strategies, etc. QA should concern itself with making sure that the process works, that the tests get run, that the tests are sound. They should do very little testing themselves.

All tests should be automated. Not only unit tests, but integration tests, load tests and acceptance tests as well.

That was an intentional lie. There are two types of tests humans should do and that can be performed by the QA-department:

  • Exploratory testing
  • Verification of aesthetics

However, nothing specifies that these activities must be done in isolation. I would prefer that the test-specialists worked in the design-teams and performed the testing together with the design team.

CI requires another thing: Every designer should be able to run most of the tests themselves from their local copy.

If you do work that likely has a big impact on the system, run some smoke-integration-tests first, before you commit to main.

Along-side or prior to a new feature is being developed, automated function tests and acceptance tests should be written. Obviously they will fail until the feature is complete. You don’t want these new tests from halting the build/deployment. So you will need some kind of mechanism that allows the developers to test against these acceptance tests but preventing someone turning the feature on. If your testing framework and CI-engine doesn’t allow you to easily exclude tests that are expected to fail, I could agree to put the test code on a “feature branch”. The reason I would allow this, is because tests, if correctly written are completely isolated and require no integration.

If you have commits that keep breaking main in a show stopping fashion, then you have the wrong set of tests and the wrong mindset. CI requires discipline; more so in the daily work than waterfall. Because you will be called on it every time you slip and break something. In waterfall, you get away with doing the wrong things for much longer, until it comes to crunch time and all the ugliness becomes apparent – or worse, does not show it self until it is running in the customers’ systems, causing havoc.

“Also, if new stuff is too unstable or there has been misunderstanding about functionality, it doesn’t have to be integrated at all.”

If there are uncertainties: discus, do pretotypes (pretotyping.org/), do internal demos. If a commit breaks the build, undo it. Also, new features should have a feature lock preventing them from showing up in the delivered product until the full feature is completed and ready for market. Large features may take months to develop to completion. Should you hold of the integration for that long? Of course not! Even if there are concerns with CI, the benefits exceed the drawbacks many times over.

You will have issues with CI and it will have drawbacks, but the alternative is far worse. So even if you don’t feel that I have addressed the stated concerns in a successful way, I would still argue that these concerns are considerably small compared to the issues that CI do solve.

Continuous Integration: A Mindset January 28, 2012 at 12:18

I attended a round-table discussion on CI (Continuous Integration) the other day – and it prompted me to write this post.

There seem to be some confusion about CI. Some have chosen to let  integration mean the interaction of two or more software components. Hence, making the conclusion, that integration is only taking place during test execution.

Unfortunate, if you have that limited understanding of what CI is, you loose the big picture. CI is not only the triggered build and test-execution on every check-in. That is only the safeguard that makes it possible to perform the actual activity; that of continuously integrating others’ work with your own.

I’ll say that again: continuously integrate others’ work with your own

That means you do not have team-branches, feature-branches; you keep it one track as much as the product will allow you to. Every change in the system should propagate to you more or less immediately.
Yes, you need builds, and test to insure that your code is always working, but the integration is not the integration of software modules or components, it is the integration of your work with other people’s work.
Someone might get irritated by the use of the word work here. Why isn’t he saying code if that what he means. Why not say that you continuously integrate other developers’ code with your own. Well, first off, “your code”, “others’ code” imply code ownership. In an agile environment, you don’t own code; it is a communal responsibility.
Second off, it is not just code that requires integration. It also applies to toolsets, platforms, hardware, environments, configurations; every aspect of the software development process.

The concept of continuous adaptation or really continuous adoptation, should be your mindset.

Using this practice, some will experience that everything changes underneath you, that you constantly need to change small aspects of your code because of others’ changes. It will become tedious and your own progress will be slow because you have to take every one else’s changes into account. You might even long back to the good old days when you could work without a care fore a month and then hand of your work to the integrator who magically just made things work together.
First of all, the integrator’s job in these situations was never easy. They often spent late nights getting yours and others’ crap to work properly. So even if it was the good old days for you, it wasn’t for them. Secondly, this was an error prone process. It created a mess that you usually ended up having to fix. So if you remember the frustrating debugging sessions due to obscure errors it isn’t so much the good ol’ days anymore.

Despite all of this, if you still find yourself longing for the old ways, it can be helpful to realize this:

Decoupling of dependencies should always be done by architecture and design in the code– never by black magic in the version control system/by configuration management.

If you are in a situation where you use the version control system to reduce the impact of changes, to create isolation between modules, this is a symptom of pore architectural design, which needs to be addressed. DO NOT hide the problem by configuration management.

In conclusion, the mindset of continuous integration is not just that of having automatic builds and automatic tests. It is the process of pulling in and integrating other developers’ work with your own. Decoupling of subsystems and modules must be done through architecture and design in the code, never through configuration management.