By Arthur Manasyan, Senior QA Engineer at Macadamian
In my recent project, I was tasked to automate the API Integration between backends of a medical device and its desktop portal. We were a team of two automation engineers, using ReadyAPI v2.7 as the automation tool and Git/Github for version control.
We were using a common process to version control the ReadyAPI project — using a composite project, each of us would create a feature branch from the master branch, work on a separate test case within the same test suite, and finally merge both branches. Obviously the first branch would merge with no issues; however, the second branch would return numerous conflicts every time. This became a serious headache as most of those conflicts were for no objective reason — working on separate test cases and not making changes in common settings should not cause any conflicts.
ReadyAPI has a Git plugin which provides a GUI interface for main Git actions, however, it doesn’t do much to auto-merge the conflicts. To resolve the conflicts, it suggests choosing one of two options — ‘ours’ or ‘theirs’. Choosing either option keeps only one side of the changes and discards the other.
This leaves you with the only remaining option of manually solving the conflicts which is a difficult task, as you have to deal with XML files ReadyAPI generates behind the scenes as you work on the GUI level.
Extensive research on the internet and the ReadyAPI official forum revealed the fact that many people had faced similar issues with ReadyAPI team collaboration.
The project went on and we needed to find some solution to these problems, so I conducted further research to see how I could find ways to make this process less painful.
After paying close attention to the nature of the conflicts I noticed that the vast majority were related to custom properties. In the project, we were using custom properties to store values on different levels — project, test suite, test case and test step. Some of these properties were static; they store values which don’t change, like username and password. Others were dynamic; they get new values with each execution, like session token, userid and others.
As two engineers working in parallel, we would have 2 branches: A and B. One of the engineers works on branch A, while developing the new test case she runs the whole project, dynamic properties are getting new values, and she pushes the branch. The second engineer works on branch B, runs the project again, and dynamic properties are getting different values in branch B. So, branches A and B now have different values for all the dynamic properties and naturally you get conflicts on all these properties. Now in order to merge your branch, you need to manually go through each of these properties and leave one of the values, which is time-consuming and inefficient to do every time.
To find a solution to this problem, first I searched to see whether ReadyAPI provides a feature to drop values of dynamic properties. The first option that I noticed is the button to clear values in properties in Custom properties toolbar. Still, this would be inconvenient because not all of the properties are dynamic, and also it would take a lot of time to click this button for all test suites and test cases in the project.
The second option would be to use the ‘Save Properties Between Sessions’ flag on the project level — empty all the values for dynamic properties and set the flag to ‘false’. Later, every time you run your tests, ReadyAPI would drop values for dynamic properties. This could actually solve the problem, but it would introduce new inconveniences, making debugging of your tests difficult. You can’t run your tests step-by-step as values needed from the execution of previous steps are being dropped after running each step, and also, you lose all these dynamic IDs so you wouldn’t have them to investigate issues in case of failures.
Given all this, I decided to implement my own workaround for the aforementioned issue.
I wrote a Groovy script to drop values for the dynamic properties, here is the code:
First, I declare a generic function clearProperties() which takes an object as argument and clears the custom dynamic properties for that object, skipping properties which take property expansion as value. The input argument is generic, you can pass a project, a test suite, test case or a test step. The script calls the function for the project and then runs a chain of nested loops, calling clearProperties() function for all test suites, all test cases and all test steps within the current project.
Having the script, here is the setup to make it work:
- Add ‘*’ character as suffix to all dynamic properties, e.g. ‘’session_token*, ‘user_id*’
- Add a test suite called ‘Utilities’ and put the groovy script there
- Run the script once to empty all the dynamic properties and commit the project with clear state
Later, in a feature branch you can work on new changes, and when you are done, run this script to clear dynamic properties and check in the project in a clear state.
Before having this script, if I just opened the project, ran it and saved without making any changes, ‘git status’ would show changes in 9 files — all because of dynamic properties. Now if I run this script, I get 0 changes for the properties.
This workaround will save you from a big number of unsolicited changes, the rest of the conflicts should be resolved manually, and I could suggest a few tips to make it easier.
Overall the approach is to observe how ReadyAPI updates project files and use this information to safely plan major changes and refactorings.
You can start with these steps:
- Explore file structure of composite projects
- Enable ‘Pretty-print’ and ‘Normalize line breaks’ flags in section ‘Merging changes’ on Teamwork page
Additionally, there are some changes which trigger modifications in many ReadyAPI files, you should be very cautious and plan out these changes carefully to avoid a myriad of conflicts:
- Changing project-level settings — affects settings.xml file
- Modifying and reordering the APIs in Projects tab
- Reordering test suites in a project
- Changing the environment
These are just the items that I have observed, more items might be added here.
The safe way to handle those type of changes is to create a feature branch, make sure no other branch is created from master branch, make the changes in the feature branch and merge.
To summarize, the Groovy script with the suggested tips could make version control in ReadyAPI composite project easier.
Update: the described issues are still relevant to ReadyAPI v2.8 released in 08/2019.