IntelliJ IDEA: Resolving Merge Conflicts in Git

When you work in a team, you may come across a situation when somebody pushes changes to a file you are currently working on. If these changes do not overlap, the conflicting files are merged automatically. However, if the same lines were affected, Git cannot randomly pick one side over the other, and asks you to resolve the conflict. In this screencast, we’re going to take a look at resolving merge conflicts.

IntelliJ IDEA: Resolving Merge Conflicts in Git

Links

Selecting dependencies

This blogpost was also published on Medium.

Open source software is everywhere. Most likely you are using some open source projects either at work and/or in your side projects.

Pros and cons of using dependencies

One of the upsides of using Java as a programming language, is that there are libraries and frameworks available to do many of the things we want to do in our projects, but don’t necessarily want to write ourselves. Using existing libraries and frameworks helps us deliver business value faster.

Unfortunately, there are also downsides to using external dependencies. The most dangerous being when security vulnerabilities are found in libraries many of us use, like the Log4Shell vulnerability in the log4j logging library that was disclosed in December 2021 and the Spring4Shell vulnerability in Spring in March 2022. These vulnerabilities were so severe that we had to patch all our services ASAP. Even if the version of a dependency you use does not have any known vulnerabilities, you might need to update them for other reasons.

In addition, adding dependencies to your project also has an impact on the size of your binary. For example, Brian Vermeer has created a demo to show the number of lines of code written versus number of lines pulled in by Spring. Granted, he admits that “this was the most useless Rest endpoint you could ever write”, but this demo clearly shows how the code pulled in by dependencies can overshadow to amount of code you write yourself.

A balancing act

This means we have to think carefully about which dependencies we want to use. Some developers try to add little or no external dependencies to their projects. This is one way to avoid the downsides mentioned above. Another argument may be that it gives you more control over the code in your project. Of course, the downside here is that you have to write everything yourself, which might not always be the best idea. For example, I’d rather use JUnit and Mockito than write my own testing and mocking frameworks.
On the other hand, we shouldn’t just add any library or framework, as we’ll have to not only implement them now, but also maintain them over time. Or even remove them in the future, which is not always easy. Some projects, like Lombok or Reactor, will be present throughout your code base and hard to remove should you ever want to (for example, when moving to Kotlin & coroutines).

Most of us will be somewhere in the middle; we don’t want to write everything ourselves, and we will use certain frameworks and libraries that offer us some useful functionality, but we also want to make sure we can continue to maintain our project without having to (urgently) update dependencies or rewrite our code because something is vulnerable or otherwise outdated.

What to consider when selecting dependencies for your project

The best time to check your dependencies is before you add them. The second-best time is now. So take a critical look at any dependencies you’re adding or already using and consider the following:

Do we really need this dependency?

To make it worth it to use a dependency, it has to solve our problem and do so without adding new problems. We need to consider if the project fits our needs. We can do so by reading the documentation, and by seeing what experience other users already have with a particular tool. Keep in mind that, just because other users are enthusiastic about a particular library, that doesn’t necessarily mean it’s right for you. Their context or use case might be different from your own. There might be other libraries out there offering similar functionality that are a better fit for your project.

Also consider how much of the library you’ll actually use. If it is only a small part, consider other solutions. For example, do we really need to import StringUtils to use it for one or several String functions, or can we write them ourselves? (And, if we moved to Kotlin since then, we might be able to replace them with standard Kotlin functionality.) Or are we already using another library for this particular problem? For example, we won’t need gson if we are already using jackson (or vice versa)?

Is the project well maintained?

If a project is no longer maintained, we run the risk of having to urgently replace it if security vulnerabilities are found. To see if a project is actively maintained, you can check when the last release was, and how frequently new versions come out; you can find this information for example on Maven repository. You can also check when the last commit was, and whether the project is maintained by one person, or a group of active maintainers. A project that depends on one particular person runs the risk of becoming unmaintained if that person no longer has the time and energy to maintain that project. Maintaining a successful open source project can be a thankless task and maintainer burnout is real. With multiple maintainers the load and risk can be shared. You might want to look into how many open Issues and Pull Requests (PR) there are, and the interaction on those Issues & PR’s. You can find this information on GitHub or wherever the code for the project is kept.

How popular is the project?

A popular project might have more stars, watches and forks on GitHub. Although these metrics don’t necessarily mean that people are using it; they might have starred it to try it out later. These metrics might be useful when comparing similar tools, but not necessarily when comparing different tools.

A widely used project will likely have more people talking and writing about it. Having a large number of users means more people who are able to help out others. It also means there are more potential contributors, but unfortunately a high number of users doesn’t always translate to a high(er) number of contributors. And just because a project is popular doesn’t mean it’s right for you.

What is the community like?

Consider whether the community is friendly and welcoming. How do they interact with their users and (potential) committers? How do they respond when issues are reported? Do they review PR’s quickly and offer constructive feedback? Friendly maintainers often make for a more friendly community.
They might be active in official support channels like Slack, Gitter or mailing lists, or help answer questions on StackOverflow, write talks and blog posts or find other ways to share their knowledge.

Is it easy to use?

Finally, consider whether the project easy to implement & use, and whether you like using it. Developers have personal preferences with regard to almost everything in software development, including which tools they like to use. If a popular framework doesn’t work for you, and you have options, choose something else!
Part of whether a project is easy to use might include how well documented a project is. Good documentation can help make it easier to use. Consider looking at the official documentation, as well as blogs and content created by users. The official documentation will (hopefully!) explain how a project is meant to be used.

What is the latest stable version? Are there any open vulnerabilities?

Once you’ve decided to import a dependency, make sure to add the latest stable version. We don’t want to add an older or unstable versions that we then have to update. And we definitely don’t want to import a dependency that has known vulnerabilities that have not (yet) been fixed! We want to keep our software secure and maintainable.

Where to find this information

As mentioned, there are several places where we can look for information about a dependency we are considering. One is Maven repository where we can find open source packages, their versions, whether there are any known vulnerabilities and more.

For example, when we look at Jackson Databind on Maven repository we see a list of versions and their release dates, we see the number of usages by other artifacts for each version, and we see a warning in red for versions with known vulnerabilities.

Jackson Databind on MvnRepository
Jackson Databind on MvnRepository

When we look at the details of a version with known vulnerabilities (Jackson Databind v2.13.2 in this example), we see the CVE number for this vulnerability which links to the details for this CVE). There is also a warning in yellow that there is a new version for this artifact with the link to that version.

Details for a vulnerable version of Jackson Databind
Details for a vulnerable version of Jackson Databind

Another is to find the project’s code on GitHub, to look at the code itself, see when the latest commit was, look at open Issues and PR’s, and check Insights for more details on contributors, frequency of commits and other activity.

Jackson Databind repository on GitHub
Jackson Databind repository on GitHub

We can look for official documentation and read (or at least scan) it to see whether the project is a good fit for us, and whether it is well documented.
Other information might take a bit more effort to find: Go into the support channels and ask questions. Search for blog posts (or YouTube videos, if you prefer) and other places where you can find information. We might even check StackOverflow to see whether there is a tag for this dependency, how many (open) questions there are, etc.

JetBrains has created a Package Search website that can be used to search for Java and Kotlin libraries and get a lot of this relevant information, including the latest (stable) version, links to relevant tags on StackOverflow, links to the official docs and the code, and if the project is on GitHub the number of stars, watchers and forks on the Information tab. A list of versions (similar to the one on Maven repository) can be found on the Versions tab.

Jackson Databind on JetBrains' Package Search
Jackson Databind on JetBrains’ Package Search

The Package Search plugin is even bundled in IntelliJ IDEA 2021.2+. So, if you are using IntelliJ IDEA, you can search straight from your IDE!

Conclusion

Carefully consider which dependencies to use, taking into account at least some of the things we have discussed here. The best time to do so is before you start using them. But don’t forget to periodically check the dependencies in your existing codebase to see if you still use them, and still want to use them based on the considerations above. Don’t be afraid to remove them if they no longer bring you value.

Keeping dependencies up to date with Maven

This article was also published on Medium.

In this blog post, we will look at some standard Maven commands that can help us manage our dependencies and keep them up to date. These are useful to see both direct and transitive dependencies used in the project, look for version updates of dependencies and plugins, and look for unused dependencies that may be removed. All of these can be useful to keep our dependencies up to date.

Pre-requisites

For the examples in this post, we are using the following tools and versions:

  • IntelliJ IDEA Community Edition 2022.2.1 – which you can get here
  • Example project from GitHub (Note: this is an outdated & unmaintained project, which makes it useful to show how to find outdated dependencies)
  • Maven 3.8.6 (optional, see note below) – Install Maven

Note: Maven wrapper

The project we are using in this example includes a Maven wrapper. If the project you are working on does not have a Maven wrapper, you will need to have Maven installed on your local machine. To add Maven wrapper to your project, run the following command in your terminal: mvn wrapper:wrapper and commit the result. Now anyone who uses the project can use the Maven wrapper without having to install Maven locally, and using the same Maven version.

Using Maven to display dependency updates

We can use Maven to check if there are updates available for the dependencies we are using in our project. Run the following command in your terminal: ./mvnw versions:display-dependency-updates.

This will display a list of dependencies for which newer versions have been found.

Command line terminal showing the `mvn versions:display-dependencies-updates` command and it's result.
Display dependency updates

As you can see, there are quite a few dependencies that need to be updated in this project. The reason is that this is an old project that was created from a tutorial years ago and not maintained since. The upside is that it is a great project to use as an example for finding outdated dependencies.

Using Maven to display plugin updates

The same is possible for plugins. Check which plugins can be updated by running the following command in your terminal: ./mvnw versions:display-version-updates.

On the example project, this provides the following result:

Command line showing the command ./mvnw versions:display-plugin-updates and the results
Display plugin updates

This project doesn’t really use a lot of plugins. Your actual projects might, so I wanted to include this command here.

Overview of dependencies: dependency-tree

To see all the dependencies you are using in your project, run the following command in your terminal: ./mvnw dependency:tree. This will return a list of the dependencies declared in this project, and their transitive dependencies:

Command line showing the command `./mvnw dependency:tree`and the resulting dependency tree for a project
Dependency tree

Of course, you can also find the declared dependencies in your pom.xml, but it’s good to have an idea of which transitive dependencies they bring in.

Filtering the dependency tree

The dependency tree for this example project is rather small, like the project itself. Your actual projects at work might be much bigger. If needed, you can filter the dependency tree.

To check where a specific dependency is coming from, use the following command: ./mvnw dependency:tree -Dincludes=<groupId>:<artifactId> containing the groupId and artifactId of the dependency you are looking for.

For example, if we would like to see where this project is getting the slf4j dependency, we would run ./mvnw dependency:tree -Dincludes=org.slf4j:slf4j-api. We see that we get this transitive dependency through Hibernate:

Command line showing the command `./mvnw dependency:tree -Dincludes=org.slf4j:slf4j-api` and it's result.
Filtering the dependency tree

For more information on filtering the dependency tree, see the Maven documentation.

Effective pom

The effective pom is the POM that results from the application of interpolation, inheritance and active profiles. To generate the effective POM, run the following command in your terminal: ./mvnw help:effective-pom.

When running this command on the the example project, the result will be fairly small, because it is a relatively small project. For a large project, the effective pom will be much bigger. If needed, you can write the effective POM into a log file using the following command: ./mvnw help:effective-pom --log-file log.txt.

Use Maven to find unused dependencies

We can also use Maven to find unused dependencies. Run ./mvnw dependency:analyze on the example project gives us the following results:

Command line showing the result of the Maven command dependency:analyse
Analysing dependencies

We see that we have “Used undeclared” dependencies, like org.springframework:spring-beans.
If we search for that dependency, by filtering the dependency tree for that particular dependency using ./mvnw dependency:tree -Dincludes=org.springframework:spring-beans we see that it is a transitive dependency from Spring-webmvc:

Command line showing a command to filter the Maven dependency tree and it's output
Filtering the dependency tree

We also see some “Unused declared” dependencies. If these are dependencies you truly don’t need, it might be a good idea to remove them from your pom.xml. (Note: In this example, JUnit is unused because the tutorial this project is based on didn’t include any tests. If that is the case for your project, consider adding tests instead of removing this dependency!)

Conclusion

Maven offers several ways to help us keep our dependencies up to date. Using the commands above can help us to keep the dependencies we need up to date, and to remove the dependencies we no longer need.

Presenting with IntelliJ IDEA

In this screencast we’re going to look at some ways to level up your presentation skills with IntelliJ IDEA.

Chapters:

00:00 – Intro
00:11 – Presentation Assistant plugin
00:57 – Presentation Mode
02:06 – Mouse Zoom
02:43 – Font
03:11 – Theme
03:48 – Tool windows
05:13 – Find Action & Soft-wrap
05:58 – Shortcuts & Navigation

Links:

• IDE viewing modes: https://jb.gg/erihcm
• IntelliJ IDEA keyboard shortcuts: https://jb.gg/z9pxdd
• IntelliJ IDEA reference card: https://jb.gg/2jyfzi
• Configure keyboard shortcuts: https://jb.gg/a81689
• Creating custom shortcuts: https://jb.gg/sn3pk1
• Source code navigation: https://jb.gg/4jpnu4
• Example code: https://jb.gg/zr7v7h

Using Git Interactive Rebase

This article was published on Foojay.io on August 25, 2022.

This tutorial will cover how to clean up your Git commit history with Git interactive rebase, both via the IntelliJ IDEA UI and from the command line.

Git interactive rebase allows you to change individual commits, squash commits together, drop commits or change the order of the commits.

This allows you to clean up your Git commit history to make it linear and meaningful, which can make it easier to understand the history of the project in the future.

Open the Git window in IntelliJ IDEA using ⌘+9 on Mac (or Alt+9 on Windows & Linux). In the Git log window we can see the commits that were made to the project.

We will use a Git demo project available on GitHub. This example uses TDD (Test Driven Development) to add a new feature.

In TDD, we start by adding a failing test, writing the minimum of code we need to get that test to pass and finally do some refactoring.

Even though we made the necessary changes in multiple commits, we don’t need to keep all these individual commits for future reference.

Using Git interactive rebase in the UI

We can use Git Interactive Rebase in IntelliJ IDEA as follows:

In the Git history, identify the commit from where you want to clean up your history. That will be the oldest commit in the series of commits you want to clean up; in this example, the first failing test that we added.

Right-click on the commit from where you want to clean up your history and select “Interactively Rebase from Here…“.

IntelliJ IDEA context menu with the option "Interactively Rebase from Here..." highlighted in blue

This will open the “Rebasing Commits” popup window with a list of the commits that were done on top of the selected commit.

IntelliJ IDEA "Rebase Commits" dialog

Notice there are several options at the top of this popup, that become active when we select one or more of the commits:

  • Reword allows us to change the commit message of a specific commit.
  • The Squash button is actually a dropdown that allows us to choose between Squash and Fixup. Both options will combine the changes made in the selected commits into one commit. If we select squash, by default the individual commit messages will be combined. If we select fixup, the commit message of the fixup commit will be discarded. You can select fixup while in the “Rebasing Commits” popup with ⌥+F on Mac (or Alt+F on Windows & Linux)
  • Drop allows us to drop one or more commits.

Changing the order of the commits

Let’s say we want to change the order of the commits; we want to keep the unrelated change, but separately from the changes for the new feature. We can select this commit and use the up and down buttons on the top left to change where in the order this commit will be.

List of commits in the "Rebase Commits" dialog window, with one commit selected.
List of commits in the "Rebase Commits" dialog window, with the  selected commit moved down.

Once we’re sure about the order, select “Start Rebasing“. We see in the Git log that the order of the commits has changed.

Combining multiple commits into one commit

Next, we want to combine multiple commits where we added the tests and implemented the new feature. Let’s reopen the “Rebasing Commits” window and select those commits.

List of commits in the "Rebase Commits" dialog window, with several commits in a row selected.

Now, because we want to combine those commits into one commit with one commit message we select “Fixup“, and then select “Start Rebasing“.

The Squash dropdown selected, with the Fixup option selected in the "Rebase Commits" dialog window.
List of selected commits in the "Rebase Commits" dialog window, shown in a tree structure ready for Fixup.

In the Git log, we can see that multiple individual commits are now combined into one commit with one commit message.

Drop a commit

Finally, we want to drop the commit with a mistake that we made. Let’s reopen the “Rebasing Commits” window, select the mistaken commit, select “Drop” and select “Start Rebasing“.

List of commits in the "Rebase Commits" dialog window, with one commits selected.
List of commits in the "Rebase Commits" dialog window, where the selected commit it shown with strike through.

We see in the Git log that the commit is dropped.

Rename a commit

Now that we have cleaned up our commit history, we might want to rename the commit where we added the new feature. We have several options to do so.

We can do so using Git interactive rebase, in the “Rebasing Commits” popup, by selecting the commit you want to rename and clicking the “Reword” button at the top of the popup. This will open a small editor pane where you can reword the commit message for this commit, apply the change to the message and select “Start Rebasing“.

Open dialog to Reword the commit message.

You can also edit the commit message directly in the Git log window. Right-click the commit you want to rename and select “Edit Commit Message” or press F2 on macOS, Windows or Linux.

IntelliJ IDEA context menu with option "Edit Commit Message" highlighted.

This will open a “Edit Commit Message” popup, where you can edit the commit message and click “Ok” (or “Cancel“) when you are done.

IntelliJ IDEA "Edit Commit Message" dialog.

See which Git commands were executed

To see which Git commands IntelliJ IDEA performed, open the “Console” tab in the Git window.

Using Git interactive rebase from the command line

Let’s take a look at how to use Git interactive rebase from the command line.

In the Git history, identify the commit just before the commit from where you want to clean up your history. In this example, that will be the last commit before we started adding the new feature.

Find the commit hash for this commit in the “Commit Details” to the right of the Git history in the Git window and copy this commit hash. (Spoiler: the commit hash in this example is 34bb0f99.)

IntelliJ IDEA Git history, showing the details of a selected commit, with the commit hash `34bb0f99` highlighted.

Open the Terminal window, using ⌥F12 on Mac (or Alt+F12 on Windows & Linux) and type git rebase -i 34bb0f99 (where 34bb0f99 is the commit hash we copied above).

Terminal with the command `git rebase -i 34bb0f99`

This will open an editor in the terminal with the list of commits that were done on top of the selected commit. Each line in this file is an individual commit.

Terminal with vi editor open, showing a list of commits.

By default, Git will use whatever you have set as your default text editor. If you haven’t set one, it will fall back to the vi editor, which is what we will use in this tutorial.

Changing the order of the commits

Let’s say we want to change the order of the commits; we want to keep the unrelated change, but separately from the changes for the new feature. We can do so by changing the order of the lines (individual commits) to reflect the order we want.

In the editor in the terminal, switch to edit mode by pressing I to be able to edit this file.

We can change the order of the lines by removing the commit we want to move from the list and inserting it in the place where we want it.

In vi, we can do so as follows:

  • Place the cursor anywhere on the line you want to move (in this example the commit “Unrelated changes”) and remove this line by typing dd.
  • Move the cursor to the line where you want to reinsert this commit (in this example, the end of the file) and type p.
  • Note: you do not need to switch to edit mode to do so.
Terminal with vi editor open, showing a list of commits. The bottom commit is highlighted.

Once we’re sure about the order, we need to save the file. Press esc to exit edit mode and type :wq to save the file.
Note: If you made changes to the file that you do not want to save, type :q! to force quit.

The interactive rebase will be applied. We see in the Git log that the order of the commits has changed.

Combining multiple commits into one commit

Next, we want to combine multiple commits where we added the tests and implemented the new feature. In the terminal, type git rebase -i 34bb0f99 to start rebasing. If you have already run this command, you can press the up arrow  in the terminal to show the last used command(s).

This will again open an editor in the terminal with the list of commits.

Switch to edit mode in the editor in the terminal. In vi, you can do so by pressing I.

For each of the commits we want to combine, replace “pick” with “fixup”.

Note that we use “fixup” because we want to use one commit message for the combination of the commits. Alternatively, we could use “squash” to combine the individual commit messages into the new commit message.

Terminal with vi editor open, showing a list of commits. For several commits `pick` is replaced with `fixup`.

Once we have correctly edited all the commits we want to combine, save the file.
In vi, press esc to exit edit mode and type :wq to save the file.
The interactive rebase will be applied. In the Git log, we can see that multiple individual commits are now combined into one commit with one commit message.

Drop a commit

Finally, we want to drop the commit with a mistake that we made. In the terminal, type git rebase -i 34bb0f99 to start rebasing.

To drop a commit, remove that commit from the list of commits. In this example, we will remove the commit “Mistake”.

In vi, we can remove a line by placing the cursor anywhere on the line we want to remove and typing dd. Alternatively, we can switch to edit mode by pressing I and removing the line manually. Press escto exit edit mode.

Terminal with vi editor open, showing a list of commits.

Save the file by typing :wq and the interactive rebase will be applied. We see in the Git log that the commit is dropped.

Summary

Now we know how to use git interactive rebase either from the IntelliJ IDEA UI or from the command line. Give them a try and use whichever way you prefer.

IntelliJ IDEA Shortcuts Used

Here are the IntelliJ IDEA shortcuts that we used.

NamemacOS ShortcutWindows / Linux Shortcut
Open the Git Tool Window⌘9Alt+9
Open the Commit Window⌘0Alt+0
Open the Terminal⌥F12Alt+F12
Select Fixup (in the “Rebasing Commits” popup)⌥F12Alt+F
Edit commit message (in the Git Log)F2F2
IntelliJ IDEA shortcuts

Git commands Used

Here are the Git commands that we used.

Nameterminal command
Git interactively rebase from a specific commit with commit hash, for example 11aa23bcgit rebase -i 11aa23bc
Use this commitpick
Fixup this commit (add changes to previous commit under the same commit message)fixup
Squash this commit (add changes to previous commit and combine commit messages)squash
Git commands

vi Shortcuts Used

Here are the shortcuts that we used.

NameShortcut
Open interactive (edit) modeI
Exit interactive (edit) modeesc
Remove line (note: not in edit mode)dd
Reinsert line (note: not in edit mode)p
Write and quit:wq
Force quit:q!
vi shortcuts

Related Links

Using Git interactive rebase in IntelliJ IDEA

Git interactive rebase allows you to change individual commits, squash commits together, drop commits or change the order of the commits. This allows you to clean up your git commit history to make it linear and meaningful, which can make it easier to understand the history of the project in the future. Let’s take a look at how this works.

For more information, see Using Git Interactive Rebase.

Use Testing to Develop Better Software Faster

This blog post was first published on the 97 Things blog on Medium and is published in the book “97 Things Every Java Programmer Should Know” (O’Reilly Media).

Book cover of “97 Things Every Java Programmer Should Know", which includes "Use Testing to Develop Better Software Faster".
Book cover of “97 Things Every Java Programmer Should Know”

Testing your code will help you verify your code does what you expect it to do. Tests will also help you to add, change, or remove functionality, without breaking anything. But testing can have additional benefits.

Merely thinking about what to test will help to identify different ways the software will be used, discover things that are not clear yet, and better understand what the code should (and shouldn’t) do. Thinking about how to test these things before even starting your implementation could also improve your application’s testability and architecture. All of this will help you build a better solution before tests and code are written.

Alongside the architecture of your system, think not only about what to test but also where to test. Business logic should be tested as close as possible to where it lives: unit tests to test small units (methods and classes); integration tests to test the integration between different components; contract tests to prevent breaking your API; etc.

Consider how to interact with your application in the context of a test and use tools designed for that particular layer, from unit test (e.g., JUnit, TestNG), to API (e.g., Postman, RestAssured, RestTemplate), to UI (e.g., Selenium, Cypress).

Keep the goal of a particular test type in mind and use the tools for that purpose, such as Gatling or JMeter for performance tests, Spring Cloud Contract Testing or Pact for contract testing, and PiTest for mutation testing.

But it is not enough to just use those tools: They should be used as intended. You could take a hammer to a screw, but both the wood and the screw will be worse off.

Test automation is a part of your system and will need to be maintained alongside production code. Make sure those tests add value and consider the cost of running and maintaining them.

Tests should be reliable and increase confidence. If a test is flaky, either fix it or delete it. Don’t ignore it — you’ll waste time later wondering why that test is being ignored. Delete tests (and code) that are no longer valuable.

A failing test should tell you exactly what is wrong quickly, without you having to spend a lot of time analyzing the failure. This means:

  • Each test should test one thing.
  • Use meaningful, descriptive names. Don’t just describe what the test does either (we can read the code), tell us why it does this. This can help decide whether a test should be updated in line with changed functionality or whether an actual failure that should be fixed has been found.
  • Matcher libraries, such as HamCrest, can help provide detailed information about the difference between expected and actual result.
  • Never trust a test you haven’t seen fail.

Not everything can (or should) be automated. No tool can tell you what it’s actually like to use your application. Don’t be afraid to fire up your application and explore; humans are way better at noticing things that are slightly “off” than machines. And besides, not everything will be worth the effort of automating.

Testing should give you the right feedback at the right time, to provide enough confidence to take the next step in your software development life cycle, from committing to merging to deploying and unlocking features. Doing this well will help you deliver better software faster.

Cukenfest 2018 — It’s all about the conversations

This article was first published on Medium.

In April of 2018, I attended Cukenfest; a BDD and Agile conference organised by the people at Cucumber. As a Cucumber user and open source contributor, this was a great way to meet some people I’d previously only chatted with on Slack, as well as hear some great talks by amazing people.

Preconference Dinner

The evening before the conference, we got together at a local pub with both conference speakers and Cucumber contributors. Here I finally got to meet people I’d been collaborating with in person! It was great getting to know them better, and discussing our experiences with Cucumber and BDD.

We also bonded over other topics, like a shared love of Kotlin , or dealing with a similar challenge of moving more towards a Software Engineering role from a tester role.

The highlight of the evening, other than meeting so many great people, might have been the discussion we had about Cucumber expressions, which were already available in the Ruby and JavaScript implementations, and have since been added to Cucumber-JVM.

Lots of smart people, with lots of interesting ideas and experiences to share.

Day one

The first day of the conference had a great lineup of talks by amazing speakers, including Dan NorthLiz KeoghGáspár NagyNat Price and Aslak Hellesøy (the creator of Cucumber). Speakers were introduced by Seb Rose, who could very well have a career as a standup comedian (you know, if this IT thing doesn’t work out).

If you’d like to read more about their talks, I highly recommend the blog by Katja: https://www.katjasays.com/cukenfest-2018-london-recap/ which also includes her sketch notes. Or watch the videos.

Speed meet

After the first round of talks, there was an opportunity for a speed meet; inspired by the European Testing Conference. The format of the speed meet was to have people draw a mind map about themselves as input to 3 minute conversations they would have with other attendants. Rows of chairs are set up facing each other and after every three minutes, people shift places so they end up talking to someone else. This is a great way to get conference attendees to talk to each other. Some people might find it a bit intimidating, but it does seem to foster more communication. The only downside for me is that it can get very loud!

Hallway track

At some point, I ran into Victoria Wiggins in the hallway. She had just done an amazing talk on neurodiversity and this provided the chance to tell her how how inspiring it was. It really showed a great self acceptance! While this led me to miss some of the scheduled talks, we had the opportunity to discuss (neuro)diversity in the workplace.

Personally, I really appreciate the hallway track at conferences, as it gives you the opportunity to meet people, and get different perspectives on things. This really reinforces the learning, as well as foster a community.

Day two

The second day of the conference was an open space, or `unconference`. This day was particularly geared towards interaction between participants.

Matt Wynne introduced us to the rules of the game:

  1. The law of 2 feet; if you’re not learning from or contributing to a session, you can walk off in search of a different session.

2. The other rules are:

  • Whoever comes is the right people
  • Whatever happens is the only thing that could’ve
  • When it starts is the right time
  • When it’s over, it’s over

This helps make sure everyone in a sessions remains interested and engaged.

Documentation

Some of us had our own sessions planned; we’d been working on improving the Cucumber documentation and wanted to see what was needed to get them live. It ended up being Matt Wynne, Sam Wright (a.k.a. Plaindocs) and myself working on the last bits and pieces and getting them live!

Later that day we had a demo session, and gathered some great feedback from participants. We’ll be slowly improving them, based on actual user feedback. But for now, we’re very happy to have them live after working on them for many months!

After conference

At the end of the day, we got to enjoy the lovely weather at the rooftop bar. We continued discussions about Cucumber, BDD, Software Engineering, working in tech, being women in tech, and so much more.

Later, a few of us went out to dinner and conversations continued, sharing ideas and experiences and getting to know wonderful people. It’s all about the conversations…

Open Source Day

The next day, we had an Open Source Day, where we got together to discuss upcoming changes to various implementations of Cucumber, as well as how to continue improving the documentation. I got to meet some more Cucumber contributors, which was loads of fun. We even managed to get a few things done!

Collaborating on open source

This article was first published on Medium.

Using open source projects has become increasingly popular. The number of companies using open source is growing. Unfortunately, the number of people building and maintaining it is not growing quite as fast.

Open source doesn’t come for free; someone is doing the work. And they could use your help!

Why you should contribute to open source

There are many reasons why you might want to contribute to open source.
Personally, I started because I was looking for a way to learn more about programming, and wanted to do so in a way where I might contribute something useful.

Then, I continued doing it because I enjoyed the collaboration and feeling useful and appreciated. Also, I did learn new things I was able to use at work. Your reasons might be entirely different!

I’ve heard people also contribute to open source to give back to the project or community, to build their CV, to “scratch an itch” (fix a problem they are having), or a variety of other reasons.

Ways to contribute

The most obvious thing you can do is to fix bugs, or add new features. If this is something you can do, please do! Unfortunately, this can take considerable time and coding skill, which not everyone might have. So how can you contribute, if you are not a programmer with lots of spare time?

There are many things that you can do that don’t involve coding and don’t (have to) take a lot of time. I have listed some below, along with some examples of my own contributions.

Writing documentation

One of the ways to contribute is by adding to the documentation. This is often mentioned as an easy way to get started. You don’t need to know how to code to do it; you don’t even necessarily need to know a lot about the whole project (depending on the change).
If you are adding content, you do need to be able to write well, and articulate ideas clearly. Other skills that might help are attention to detail (like spelling and grammar), coming up with good examples, etc.
Even if writing is not your strength, there are still many ways in which you can help:
* Read documentation to see if it is clear and complete. If not, offer suggestions on how to improve it. Or at least inform maintainers what is unclear to you and why.
* Fix small things, like typos or dead links, if you can. For example, some small contributions I’ve made were fixing a dead link in the Docker documentation and fixing a typo in a Pitest error message.
* Let maintainers know if you find typos, dead links, mistakes, outdated or missing information. It’s really hard to keep a fresh eye on documentation you might have rewritten and edited multiple times!
* Add information that is missing, especially if it is something you had to find out for yourself (either with or without the help of the community). Someone else might have the same problem.
* Add (links to) relevant blog posts. If the blog post is your own, consider adding relevant information from your blog post to the official documentation also. You can still offer a different perspective in your own blog.
* Review any open PR’s (pull requests) on the documentation. Look for the things mentioned above: it is clear, complete, correct? Do you see any typos or other mistakes? (Have I mentioned it’s hard to spot typos in something you’ve been working on for a while?)
I, for one, love getting reviews on my documentation PR’s; the suggestions make them so much better! And I love how this makes each PR the product of collaboration, rather than one person.

And for all of these: if it is something you can do yourself, please do so!

Answering questions

As a user, you can probably help other users with problems you have faced before. Remember, someone probably helped you in the past in one way or another. Share what you have learned!
And if you notice a lot of similar questions, consider adding to the documentation. We have recently added a FAQ page to the Cucumber documentation, and would love additional contributions to the page. Other projects probably will too!

Creating an issue

The least you can do if you encounter a problem, is create an issue. Maintainers might not all use the project in the same way, and might not be aware there is an issue unless you tell them.

Before creating an issue, please check that there isn’t an open issue for the same problem (prevent duplication). If there is, you might be able to add additional useful information to that issue.

If you are not sure you have found a bug, please contact the community to ask them. Most projects will have one or more ways for you to ask questions (Gitter, Slack, mailing groups, etc). It will often be quicker to get help that way, as more people in the community can help you (not just the maintainers who monitor GitHub issues). This might also start up a dialog on what the exact issue is, how to reproduce it etc. which will make it easier to fix.

When you do create an issue, please be as specific as you can and provide sufficient information to help maintainers understand and reproduce your issue. Many projects use templates requesting the type of information they need; make use of them! Or, if they don’t use a template yet, maybe you can add one to the project?

And again, if it is something you can fix yourself, please do!

Reproducing issues

When someone opens an issue, a maintainer needs to look at it to understand the problem. This is where you can help! Is the issue clearly described, and does it contain sufficient information to reproduce the issue? If you can reproduce it, you might be able to provide additional helpful information.
And if you can’t, you could ask the original author for more information. Or maybe the issue can be closed!

Add unit tests

If you know how, you could try to add a unit test that reproduces the issue, which both shows there is an issue and will help getting it fixed. And if you can, fix it yourself. My first contributions to Cucumber-JVM were unit tests; the first one to show that a particular (old) issue had already been resolved, and another to reproduce an issue. Fortunately, I was also able to fix it too!

Labelling issues

Many projects on GitHub use labels, to signify the type of issues. Which labels are used will vary per project, but using labels can help people either find an issue similar to theirs (preventing duplicate issues from being created), or help people find issues they could contribute to.
Adding the right labels to issues can help both maintainers and users of the project, and is something other maintainers might not have time for.
Note: as far as I know, you do have to have access to the project to be able to add labels, so this is not something you can do when you first get started.

Review PR’s

Reviewing incoming PR’s can be a lot of work. If you are not too familiar with the code base, you might not be able to say anything about the overall usefulness or direction of the PR, but you might still be able to help. For starters, you could check the readability of the code, see whether the test coverage is good, look for typos, etc. Alternatively, you might be able to build the branch locally and test it yourself to see if it solves whatever issue it was designed to solve. Even if you can’t read code, you can probably still review documentation PR’s (see above). Reviewing PR’s can also be a great way to gain experience with reading code, and to get to know the project better.

Testing new features or versions

Maintainers and contributors don’t always have time to extensively test new features or versions. This is where you can help! Create a new project to test the new feature, or upgrade your existing project to the new version (even if it is still in development). Provide feedback to the people who are working on it.

Note: there might not be open issues registered for test work. That doesn’t mean it’s not needed! You might hear about test work that is needed, when you become a more active member of the community. If this is something you’d like to do, but you are not aware of anything that needs testing, ask the community! Even if they don’t have anything right now, they might ask you in the future.
For example, when Cucumber expressions were being implemented in Cucumber-JVM, I tried them out with a small sample project and reported my findings to core maintainers, as well as made some notes on things that should be added to the documentation.

Cleaning up code

Projects might also benefit from refactoring or cleaning up code. There will be plenty of ways the code could be improved, especially if they have been developed over several years by different developers.
One of the PR’s I did on Cucumber-JVM recently, was to make use of a parent pom.xml. This removed a lot of duplicate dependencies from the project. While doing this, I also learned more about Maven, which I have since been able to use at work.

Upgrading dependencies

If you notice a project is using outdated dependencies, see if you can upgrade them. Especially, if the older versions contain security vulnerabilities. Note that some projects might introduce breaking changes, so always make sure that the project still works with the upgraded dependency. For example, I have updated Jackson dependencies on GraphQL, due to some security issues found in older versions of Jackson.

Other

There might be other ways for you to contribute. Even if you’re not a programmer, you might have other skills that are valuable to a project.
If you do have ways to contribute that are not mentioned here, please let me know in the comments!

How to find a project to contribute to

There are several ways to find a project to contribute to.

Websites

If you have no idea where to start, there are several websites that list projects looking for help:
* GitHub itself offers some suggestions on choosing projects.
* Have a look on CodeTriage for projects with open issues
* Look for issues by project, label (like “good first issue”) and/or tag (for example, your preferred programming language) on Up-for-grabs
* You can also find these links and more on First Timers Only

Projects you use yourself

A great tip on where to get started, is to help out with a project you use yourself. You’ll be more familiar with this project, and you might even be able to solve your own problems. If you are already be part of their community, you’ll have a better idea of what is needed.

Focus on welcoming communities!

Focus on projects that welcome new contributors. Some of the following might help:
* See if there are any issues marked “first timers only”, “good first issue” or something similar; this would signify they are open / looking for new contributors and give you an idea of where to start.
* See how they respond to issues created or PR’s opened (do they ask for more information in a polite or a hostile way, how constructive is feedback on PR’s or issues)
* Check to see if there is a code of conduct, contributing guidelines or things like that (and whether they are enforced)
* Join the communication channel(s) to see how the community interacts

Know that there are plenty of projects and communities out there who would love, love, LOVE your help! And I hope you find one, if you are looking.

Personally, I was very lucky to find the Cucumber community, who were very welcoming and helpful. When I first started, I accidentally merged something that shouldn’t have been merged yet. Unfortunately, I didn’t know a lot about Git yet, but several core maintainers helped to fix the problem (and were still nice to me). I spent the weekend doing Git tutorials, so this would never happen again! Learning more about Git has been very helpful at work; I’m even able to help out coworkers at times.

Reasons not to contribute to open source

While there are many reasons to contribute to open source, there might also be reasons not to do so.

Employer or contract doesn’t allow it

This might be a valid reason for you not to contribute, especially to the code. You might still be able to help the community by answering questions from other users, sharing your experience, creating issues or adding relevant information to them.
If your employer uses open source projects, they will also have an interest in keeping the project maintained. Instead of letting their employees contribute code, perhaps they could become a sponsor? Cucumber, and several other projects, accept donations through OpenCollective; others use Patreon, or other options. Recently, one of my coworkers donated his education budget for the year to an open source project he uses at work. I think that is a great idea!

Being a noob…

Please don’t underestimate the value of a fresh pair of eyes! Documentation, especially beginner tutorials, should be easy to follow along even for people who are new to the project. The project itself should be easy to use. If they are not, this is your chance to provide valuable feedback!
If you are having any problems when using the project, contact the community and let them know. And if they take the time to help you out, why not document what you have learned for the next person who comes along?
Even if you are not having any problems right now, you can still read the documentation and provide feedback (see above).

Not sure this is a bug, or how to fix it

If you have a question, please find out how to contact the community. Many projects have an active user community willing to help you. If you’re not sure you’ve found a bug, just ask them. They’ll let you know whether you should log an issue. They will also ask you for the information they need to fix it.
If you want to add a feature but don’t know how, there might be people to help you get started. They could point you in the right direction of where to make the change, or provide insights on where the project is going.
Proposing your change before doing a lot of work on it, will also prevent you from building a feature that might not be in line with the direction the project is taking.

Don’t have time

Again, fair enough. You might have other priorities in your life.
Not all contributions have to be big or take a lot of time. There might be small things you can do. You might be able to do them at work, if they are related to your work (and your employer allows you to!). Even engaging with the community, by asking and answering questions, or logging issues, can be very helpful!

Come collaborate with us!

Open source software isn’t free — someone else paid for it.

However you are using open source, and however little you feel you have to contribute, there are plenty of small ways you can make open source better.
I hope I’ve given you some ideas to try. Please go and find a way you can contribute to your favourite open source project!

Overview of cucumber community
Cucumber community