What was our project? What did we expect to do in the project?
The project assigned to us is entitled Junit + Selenium. Unlike our fellow interns, our work is focused on testing already existing codes from the company rather that develop and create one. After knowing that this is our project, we felt a little of we-think-this-is-easy and oh-something-new-to-learn. It was exciting to see that we will be delving into the lesser appreciated side of programming, while also getting to know new tools that can further aid the goal of testing the software.
Being familiar with the concept of JUnit testing and Test Driven Development beforehand, we were actually surprised that the creation of these modules was assigned to us. Having little to a decent amount of JUnit testing, we instantly thought of testing classes that doesn’t require much when it comes to the tracing part. We expected a type of testing where we will be thinking of critical test cases that will be of help in understanding the capabilities of the algorithm (such as those programs that are leaning towards mathematics). But then again, we don’t have the best foundation of the said practice, so we didn’t know what else to expect outside of seeing several @Test, assertEquals, assertTrue, and assertFalse.
Enough of our thoughts on JUnit. What really made us have mixed feelings is the Selenium part of the project title. Although this isn’t the first time we’ve heard of Selenium test automation tool, this is the first time that we are actually gonna have a close encounter with it (or at least we think we will). The idea of automating tests that would’ve done by a human through keyboard input and mouse clicks is very intriguing for us. While we were excited to see how we would be able to create these automated tests, we also thought of it as a challenge that we will hopefully be able to surpass.
Other than these opinions, all we could think of is how things will play out for the rest of the internship experience. “We could do that, no sweat”, our minds echoed as we continue to wait for the day that we will start our program.
The first week in! How was it?
It. Was. Terrible.
But in all seriousness, though, little did we know about the existence of Mockito. For people like us who are almost always in the analyst and developer side of software engineering, implementing the way of thinking that Mockito encourages is incredibly unique.
The process of test creations using Mockito was hard, especially because we haven’t tried testing classes that have dependencies in them. As said as it was, we are not exaggerating that Mockito had us lost for a solid week. Despite being able to pass an output containing the theoretical explanation of Mockito, we weren’t able to let it sink in an applicational level. There was a point within this week where we injected mocks for classes that have no need for mock because we thought that it is necessary to mock everything. What’s worse is that we even tried to mock the class that we are testing. And guess what, we actually left the test as is, not realizing the mistake that we had done until the following weeks (keep this in mind). Mockito was mocking (heh) us for being unable to use it in our tests properly. It also didn’t help that the code we were testing either didn’t make sense (*stares at repository*) or were too deep (*stare at util*) for us during these times.
What happened half-way? Was it too much?
As the testing for DMS progressed, the test creation continued to become more of a coding-via-pattern type of testing as opposed to the usual type of testing we did in our colleges, which focuses on actually creating critical test cases (partly because testing is done for those involving complex computations instead. Luckily for the both of us who worked in the JUnit test modules, we were able to find a ‘niche where we are able to maximize work efficiency’. While one of us is able to produce test cases for the different object classes (such as entities), the other is in charge of testing the different utility functions. As the days continued, it felt like the job was getting easier, but by the time that we have finished the whole folder of packages (that of course, contained different tested classes), things went a little sour. Aside from Mockito, two other tools were introduced to us. While the first one Phabricator is mostly for Sir Gino’s (our supervisor) way of monitoring our work, the second one was to actually check if we covered all the lines and branches that each class has. This has created an opportunity for us to quantify our progress in testing the application. But remember how we described our experience with the testing during the start of the program? Because most of the things we have done wrong or had a low line and branch coverages, we basically had to restart the codes that we have done, the most notable one being AuditUtil.java (which still didn’t reach a line coverage of 80%).
Around mid-February, we were then tasked to implement Continuous Integration (CI) with the help of an automation server called Jenkins. Setting up the system was easy since Sir Gino guided us along the process, but the time to finish the step-by-step process took us quite a while because of a number of Maven dependencies both Document Management System and OpenTides4 needed to download.
In all honestly, we believe that the project has its own share of easy and difficult rounds. It was especially refreshing to be able to prepare test modules and focus on understanding on how other people are able to work around different problems in the industry level rather than creating the code ourselves.
What matters did you attend to towards the end of the internship program?
Towards the end of our project, our team was assigned in continuously creating JUnit for OpenTide4 and setting up a visual line/branch coverage tracker (the index.html display of Cobertura’s generated report) along with the email notification service for the projects we tested (meaning both DMS and OT4). With that being said, we then decided to split the work again, with one of us adding the email notification to Jenkins while the other continues to create the test modules. Of course, shortly after, the one who created the email notification service joined the other in continuing the creation of these tests.
Were we always working during the internship opportunity?
While it seemed that we were always working (we’re really not, trust me), every once in awhile, our company conducts activities that keep things balanced. Ranging from company activities to lunch-outs, our company is doing its job to help us maintain a good work-life balance during our stay. There are probably a lot to mention, but these are probably the most iconic activities that we’ve joined:
Lunch Out with CEO, Mr. Allan Tan
As one of the first non-work related activity that we did with some of the employees of the company, including Mr. Allan Tan. It was something that allowed us to get a chance to be with the different people within Ideyatech’s community and how they wish to help us, and other employees that matter.
Tuesday Tech Talks(T3)
Every Tuesday, employees stop work and come together in the Tech Bar (which is the company’s eating area/hangout area) to attend a talk prepared by one of the employees of the company. The assigned individual will be discussing any knowledge that they wish to share within the whole Ideyatech community. Despite being called a ‘Tech’ talk, the speaker will be free to talk about anything as long as they will be sharing something new to the employees. This allows participating individuals to learn programming practices and tools, life skills, or even business related matters.
The company creates avenues for the employees to have fun and enjoy things in a more personal sense rather than a business centered one. These monthly activities happen during the end of everyone’s shift on the Friday of the third week of the month. While employees have a choice to not attend the activity, the event almost always is attended by most of the workers that were present during the office hours. Attending these events will not only enable the employees to have fun, but they will have the chance to bond with the other individuals in the company, which allows them to work better as a team.
In the past 2 months, we were also able to take part in these joyous events. For the month of January, the activity focused on a Game Night centered theme. Games of different kinds were present during the night. From Card, Kinect, and Computer games. There was also a performance presented by us, interns during the event. This allowed us to feel more comfortable in front of them during the rest of our stay (and it did work). For the month of February (which is also the birth month of Mr. Allan Tan, our CEO), the company conducted a Formal Night. In this event, we celebrated our CEO’s birthday and had fun games such as the heart matching games, paper dance, and a blindfolded trip to Jerusalem. All of us were given the opportunity to perform again just like in the Game Night and so, some of our fellow interns sang some songs.
What did you learn during your stay in the company?
Now that all our personal experiences are out of the way, we will be going a bit technical on what we’ve done for the past two months in our project JUnit + Selenium.
JUnit is basically a framework used to test different classes. This is the core of our work in the project that we did. Without it, we will not be able to continue with the project. The framework makes use of functions in the Assert library in order to check whether actual results are matching the expected results (although sometimes, it doesn’t when tests are of types of smoke tests, but that’s for another day). The Assert library contains commands such as assertEquals(), assertTrue(), assertFalse() and assertSame() and fail() in order to make the tests intuitive and understandable to others who are reading the code.
In practice, created tests should:
1. Contain the name of the class appended with the work ‘Test’ (e.g. Checker – CheckerTest)
2. Be separated per function in order to easily check for mistakes in the long run.
3. Have a function that possesses names containing information on:
a. The function being tested
b. The state being tested
c. The expected result/behavior (only used sometimes due to the length of the function names)
This is done to ensure that each test serves specific purposes rather than being redundant. By creating JUnit tests following the right practices, it will be easier to check if there are mistakes that are done during the development process. JUnit in itself, however, does not possess the ability to be able to test classes that have dependencies. In order to give JUnit the ability to do so, another framework is used.
Mockito is a mocking framework that enables the users to mock the variables (known as dependencies) needed by the classes in performing specific functions which are required in order to allow normal
execution. Simply put, Mockito is used in hard coding the result returned by the functions within any properties used by the class. This also applies to the variables passed by.
Mockito has played an important role in allowing testing classes with dependencies. By being able to mock the variables that are part of the actual functionality of the class, it will be easier to trace the code and prove that bugs and/or defects exist within it rather than its dependencies.
While still following the common coding convention prescribed in the JUnit section, Mockito was added and used both in mocking an object’s property and a parameter. Although two of the items were mocked, the myObj in toTest. In order to make the mocking more useful, the when() function is used to allow the user to ‘hard code’ the return value of the mocked variable. This allows the functions input.getValue() and myObj.getValue() from MyClass to execute properly.
Despite having the ability to test the code and understand the different ways to cover dependencies, it is also important to have a quantifiable measure of which were already covered and which weren’t tested.
Cobertura is a java tool that allows developers and testers see lines and branches covered by the created tests. This tool takes into account the different branches (or conditionals) present within the class and the lines that are covered by each branch.
While it is okay to use create tests without the use of these tools, the use of Cobertura aids the user in tracking which tests are needed and which are redundant.
Jenkins is an open source automation server that can automate non-human tasks such continuous integration. This helps maintain a project from bugs that cause an error as this automation server tests a set of test scripts regularly and will then send out reports regarding the results to the developers. In order to better utilize the server, several plugins were added, including:
1. Git Plugin. Simply put, this plugin allows the integration of Git projects into Jenkins.
2. HTML Publisher Plugin. Though the use of this plugin, the Cobertura line coverage reports were displayed at the main page in order to keep the tracking of the coverage easier.
3. Email extension plugin. By using this feature, it will be clearer for the team to know who broke the code and when the code was fixed (meaning, from unstable to stable status).
Realizations during the Internship program
Once again, as individuals who are more inclined in developing more than testing, there are a few things that we have realized while engaged in the internship program.
- Each and every opinion matters. As a team that is focused on creating JUnit tests, it is crucial that questions such as ‘why’ and ‘how’ will always matter. This might be an opportunity for developers to understand possible mistakes and possible defects that might come up in the future.
- Confusion is a double-edged sword. While confusion can be a good indicator to tell if a class code has problems within its functionality, that is not always the case. For seasoned developers, this can be a baseline, but for other fellow developers who are working their way up the ladder, this might be a product of a lack experience. Do not hesitate to ask when there are unused parameters and variables within the code. Most defects come from these kinds of logical error.
- Learn to pause. Despite being in a fast-paced world where being first is almost always important, it is not bad to take your time in understanding a piece of code. I personally find it better to be able to produce a test that goes in-depth with the testing process rather than a rushed one that had no meat to tear into, and last but not the least
- Do not belittle yourself. Let’s admit it, testers are usually the least appreciated individuals in a team because of the nature of their job. They question other’s code, they look for ways to break a code, and worse, they halt codes from going into production. Instead of approaching it too negatively, think of it in a different perspective. It is better for us to catch these mistakes done by the developers because this allows the code to be refined in order to give the best results to future users. If you’re receiving more hate, then that means that you’re doing your job well (or you’re being too forceful).
Did we enjoy it? How did the experience feel like?
Now that we are nearing the end of our internship experience, it would be safe to say that we were satisfied with our stay in Ideyatech, Inc. With this being said, we also want to express our personal thoughts on the experience.
Benson R. Polican
Winfred Louie D. Villaluna
Related Article: Internship Experience: Document Classification