Why it is considered bad to use open dependencies?

Why it is considered bad to use open dependencies?

Understanding most common versioning system

What is an open dependency?

Dependency is considered “open” if you don’t fix it to a particular version. In practice, it means that the next time you “build” software the most recent version of the dependency will be used.

# that's closed (fixed) dependency

# that's open dependencies
# that's open dependency with lower bound.

# that's hybrid dependency

It is usually considered a bad practice to use open dependencies. It is usually OK to use fixed dependency and it might be OK to use hybrid one. Before I explain why let’s consider the most common versioning system.

Understanding versions

There’re many conventions for versioning software, but one is used most often. Arguably the only right one. Let’s consider it: {majour version}.{minor version}.{hotfix/patch} The last part is optional. For example:

version = 1.3.4
# or
version 1.3

Using this convention is very handy for libraries. And here’s why.

Majour version updates

All potentially breaking updates are considered major. When you change the first number of the version you’re essentially saying to library users: “it’s likely you will need to update your code to be able to use this library”.

That’s probably one of the reasons why the Java version was 1.6-1.8 before they changed the versioning logic.

Minor version updates

Minor version updates are supposed to be backwards compatible. I.e. while it’s perfectly OK to add new features and fix bugs in minor version updates, all the previous functionality is supposed to be working as it did before.

Think of Java versions again.

Patch updates

If there’s no patch - there may be no patch update version (or it may be “0” - like 1.3.0). These are often used for minor bug fixes. Must be safe to update.

So why using open dependencies is bad?

Simple - it is risky. There are three main risks:

  • Breaking changes

  • Risk of regression

  • Transitive dependencies hell

Breaking changes

Any major version update can (and usually does) include breaking changes. It means some methods/classes can disappear or change API in a way that you need to rewrite your code. If you leave dependency open - you may find your code broken every other time you rebuild the code.

Risk of regression

Even minor updates can be risky because they create a risk of potential regression. Even though it’s almost guaranteed that the API of the dependency won’t change, there’s a risk that behaviour will. Either a new bug will appear, or maybe the bug your code was depending on will disappear. That’s bad - because now you’re not in control of your code behaviour.

Transitive dependencies hell

Any dependency is likely to require another dependency. Quite often two or three different libraries will use one common library. Let’s consider this example:

  1. You add Selenide=4+ as a dependency. Version 4.1 is downloaded, which requires Selenium=3.4.5.

  2. You add Serenity=5+ as a dependency. Version 5.0 is downloaded, which requires Selenium=3.4.5

  3. Selenium=3.4.5 is downloaded, and everything works

You build and test your code - everything is fine. The next day you build your code and here’s what happens:

  1. Selenide stays 4.1, and it still requires Selenium=3.4.5.

  2. Serenity bumped up to the most recent version 6, which requires Selenium=4.0.0

  3. Two possibilities: either Selenium=4.0.0 is downloaded and you find really strange runtime issues or the build is randomly breaking and you’re scratching your head why.

So what do I do?

Depending on your risk tolerance or paranoia level you can:

  • Use fixed dependency version. The safest option, but it will require you manually update the version for security fixes.

  • Leave hotfix/patch version open. This is a compromise in a hope that all security fixes are included as hotfix/patch updates.

  • Use the Minor version open. This should eliminate risk of breaking changes and get most of the security fixes, however, the risk of regression and possibly transitive dependencies hell is present.

Hope it helps.

P.S. Did I miss something? Made a mistake? Point this out in the comment section!

P.P.S. The original article is published here: https://testclub.notion.site/Why-it-is-considered-bad-to-use-open-dependencies-66cf2cd4fc404f12a58bad039df12965