Category Archives: CS-443

Blog Post #1 JUnit 5 Testing

In class, we have been learning about testing with Junit 5 and doing assignments related to it. After watching the video for the advanced part of the assignment,  I decided that I wanted to research further into the topic for my first blog post. So, what is Junit? In a short answer, JUnit is a Java open sources unit testing framework that is used to write and run repeatable automated tests. JUnit 5 Is the updated version of the highly popular testing library that is Junit 4 which I’m sure you all have heard of it. Junit 5 was released in 2017 that adds good use for Java 8 features. In fact, JUnit 5 requires Java 8 JDK or higher to work.

While researching a few of the key differences between the two versions are Junit 5 is composed of 3 sub-projects JUnit Platform, JUnit Jupiter, and JUnit Vintage. The Assertions and Annotations have been changed, and most importantly Junit 5 adds the support of the lambda expression in which we went over in class. One of the blogs I read recommends doing this example,  which I found quite helpful and easy to understand. The code below is just a conversion between Fahrenheit to Celsius and Junit to test it. The author breaks each part down into subsections which made It easier to follow along. I was also, curious about how Junit 5 worked in the Gradle so I followed tutorials to see how the build systems provide supports to the new feature. I highly recommend watching the video that I have provided; it explains everything you need to know about Junit 5 and the architecture behind It.

 

Resources: 

https://www.youtube.com/watch?v=flpmSXVTqBI 

https://www.parasoft.com/junit-tutorial-setting-up-writing-and-running-java-unit-tests/

From the blog Derin's CS Journey by and used with permission of the author. All other rights reserved by the author.

Test Driven Development

Link: https://www.thoughtworks.com/insights/blog/test-driven-development-best-thing-has-happened-software-design

            The article linked above talks about test driven development, also referred to as TDD, and how it effects software development. I specifically chose this article since it centers around a topic that we’re supposed to cover in this class. The author explains three key reasons why this type of development is used. The first reason is that test driven development is an iterative cycle comprising of the three steps of failing tests, passing tests, and refactoring code. The “failing tests” phase establishes a baseline to work with, the “passing tests” phase develops that baseline into code that meets minimum requirements, and the “refactoring code” phase further develops that code. The second reason is that TDD forces a developer to question their code on multiple levels. For example, a developer would be pushed to question how a specific component works or what they expect from their code. The last reason is that test driven development allows for faster feedback on software design as poor design is often the reason why testing features fail. The article goes on further to explain how to apply TDD on code that is impossible to test.

            Reading this article, I found myself agreeing with a lot of what the author had to say. What stuck out to me in particular was how TDD forces a developer to question their code. It got me thinking about the habit I developed writing code where I began to write down and plan the general structure of a whatever project I worked on. The way that test driven development pushes someone to understand their code in what component does what reminds me of my habit but on a smaller scale since a developer would usually test a single feature at a time. And this type of development is really a new concept for me since I’ve used that iterative cycle that the author mentioned without even realizing it. The only major difference is that is that I typically didn’t use a test class which is what I’d assume is a given in the context of the article. I usually manually tested my projects which obviously hurt my productivity and deprived me of the benefit of faster feedback in TDD.

From the blog CS@Worcester – Rainiery's Blog by rainiery and used with permission of the author. All other rights reserved by the author.

Getting my feet wet with the JUnit 4 Runner Architecture

Recently as part of a homework assignment, I learned that in JUnit 4, you were only allowed to use one test runner. This aspect of Junit 4 intrigued me so I decided to do a little more research into the architecture of the JUnit 4 Runner Class.

https://www.mscharhag.com/java/understanding-junits-runner-architecture

In this blog by Michael Scharhag, he explains generally what are Runners, how they work and the class hierarchy. Throughout the post, he walks us through the class hierarchy by using a series of tree diagrams and code snippets. He also explains some of the more easily missed details such as what happens when we don’t pass a Runner to the @Runwith annotation. He also talks a little bit about possible pitfalls such extending the wrong class and some neat tricks you can do with the JUnit 4 Runner such as creating custom runners. Overall, I feel like this post was more on the technical side and I used the following video to look at more of the application side.

In this video, it talks more specifically about what each of the classes in the hierarchy do and what annotations to include and when.

From the blog CS@Worcester – Just a Guy Passing By by Eric Nguyen and used with permission of the author. All other rights reserved by the author.

JUnit 5

This week we had our first assignment. This assignment was about practicing writing JUnit 5 test cases. I am familiar with Junit 5 test cases from another computer class in last semester. Because I haven’t used Junit or coding in java for a while it took me a while to remember what I knew and how to code the test cases. JUnit 5 is most widely used testing framework for java applications. For very long time, JUnit has been doing its job perfectly. In between, JDK 8 brought very exciting features in java and most notably lambda expressions. JUnit 5 aims to adapt java 8 style of coding and several other features as well, that’s why java 8 is required to create and execute tests in JUnit 5.

In this homework, we had a BankAccount class and create at least one test class for the Bank Account System using Junit 5. In the base assignment we had to write the test for the methods that were in the BankAccount class and at the same time create a private method. In the intermediate we had to the write tests for which may include Custom Exceptions. In JUnit 5, to test methods which throws exceptions, we should use .assertThrows() method from org.junit.jupiter.api.Assertions class. The assertThrows() method asserts that execution of the supplied executable block or lambda expression which throws an exception of the expectedType.

In the advance I had to watch a podcast from Sam Brannen, Deep Dive into Junit5. The podcast was very interesting. From here I learned the fun fact that Junit5 is called Jupiter, the reason is Jupiter happens to be the fifth planet from the Sun. He explained some advantages and differences that Junit 5 has over 4 like; JUnit 5 has new features for describing, organizing, and executing tests, especially the display names and can be organized hierarchically, Junit 5 can use more than one extension at a time, you can easily combine the spring extensions with other extensions etc.

Overall, I really enjoyed working in this assignment even though I had to refresh my skills in java and writing test cases has always been a challenge for me but that doesn’t mean that I will give up.

https://howtodoinjava.com/junit5/junit-5-vs-junit-4/

From the blog CS@Worcester – Tech, Guaranteed by mshkurti and used with permission of the author. All other rights reserved by the author.

A Third-Week Software Testing Student’s Attempt To Teach You About Testing Automation

Christian Shadis, 02/28/2021

I find teaching topics you are currently learning to be an extremely valuable way to supplement that learning. So, in this blog post, I will walk the reader through an in-class activity from my CS-443 Software Quality Assurance and Testing class, while providing further context and explanation to demonstrate understanding of the material.

If there’s anything I’ve learned in my three years as a Computer Science major, it’s that my code is definitely going to have bugs. Lots and lots of bugs. I remember spending hours trying to debug a program for one of my courses, only to realize that I had tried to compare two strings in Java with ‘==’ instead of the ‘equals()’ method. In those hours, I ran the JUnit test suite provided to us dozens of times. While test automation wouldn’t have solved my problem that day, it does solve a very real problem developers face: running tests manually and repeatedly. In this post, I will use my limited experience and outside reading to provide some top-level understanding of what testing automation is, and how to implement it in your projects.

It may be practical for a student to click the ‘Run’ button over and over again to troubleshoot their code, but in a professional environment with large projects (even multi-project builds), this quickly becomes cumbersome and costly. We can automate testing by forcing unit test suites to run any time a repository is updated – in this example I will be using Gradle and GitLab.

To begin, we must understand the basics of the concept of a build. According to https://www.techopedia.com/definition/3759/build, a software build is the process by which source code is converted into standalone executable scripts. Gradle is a well-known build tool that allows the developer to use test automation. Visit https://gradle.org/install/ to install Gradle on your computer.

Open a basic project. For this post, I will be using some very simple Java code from an in-class activity that models a Rectangle object:

public class Rectangle {

    private int height;
    private int width;

	public Rectangle(int height, int width) {
		this.height = height;
		this.width = width;
	}

        public int getArea() {
                return height * width;
        }

        public boolean isSquare() {
                return height == width;
        }
}

Now that we have our main code, we need to write some JUnit 5 test classes:

// We need to import some testing modules
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class RectangleTest {

    @Test
    void testRectangleArea() {
        Rectangle r1 = new Rectangle(2, 3);
        int area = r1.getArea();
        assertEquals(6, area);
    }   

    @Test
    void testRectangleNotSquare() {
        Rectangle r1 = new Rectangle(2, 3);
        boolean isSquare = r1.isSquare();
        assertFalse(isSquare);
    }
}

Now that we have a class and a test class, we are capable of manually running tests in our IDE. All tests, of course, will pass. But as we work on our project, expanding our code and our test classes, we want tests to run every time we push our changes to the remote repository – this way we know if any new changes have broken any old features. So, let’s configure this project to do exactly this.

The first step to automating our testing is to create a build with Gradle. Open a terminal, and navigate to the top-level folder of your project:

Run the command gradle -v to ensure Gradle is installed on your machine. If the version number of Gradle appears in your terminal, it means your installation is complete. Now run the command gradle init to establish the folder as a gradle project. Now go through the options, selecting all applicable choices. For example, I chose the following:

If you now examine your project folder, you will see an entirely different structure. In the folder lib/src, you will see two other folders: main and test. These folders are where our code for our classes and tests will be moved to. Move Rectangle.java (or your equivalent file) to lib\src\main\java\[package_name]. You will see another file, Library.java, in the desired location. Similarly, move RectangleTest.java (or your equivalent) to
lib\src\test\java\[package_name]. You will see another file, LibraryTest.java, in the desired location.

From the top-level directory, you are now able to run gradle build and gradle test commands. These commands will return no errors if all your unit tests pass. If one is faulty, however, you might see something like this:

Now we can also integrate this Gradle project with a Git repository. Create a new project on GitLab, and follow the instructions given for importing an existing folder to a new project. You will need to run git init command and set a remote origin URL.

Note: If this is your first time using GitLab, you will also need to create an SSH key pair – you can do that by clicking on SSH keys in the left-hand panel of User Settings and following the directions there.

Now that we have a git repository, try running the following commands to update it. First, navigate to the correct directory in your terminal. Now, run these commands:

git add .
git commit -m "Add comment here"
git push origin master

See my output below:

If you did this correctly, your remote repository should now have all of your files in it! If we want to integrate Gradle with Git, we can trigger gradle build and gradle test to run every time we push a new commit to GitLab. This removes the need to run tests manually, and is useful in informing developers if all code is still working at the time of the push.

To accomplish this, we need to use GitLab’s Continuous Integration (CI) tool. Read more about this tool at https://docs.gitlab.com/ee/ci/. The idea behind the tool is to build and test the code before merging changes with the existing repository, adding an extra layer of protection for your code. GitLab uses a specific file, .gitlab-ci.yml , to format the execution of its continuous integration. There are templates available online, such as at https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml. For simplicity, I copied and pasted the code below:

# This is the Gradle build system for JVM applications
# https://gradle.org/
# https://github.com/gradle/gradle
image: gradle:alpine

# Disable the Gradle daemon for Continuous Integration servers as correctness
# is usually a priority over speed in CI environments. Using a fresh
# runtime for each build is more reliable since the runtime is completely
# isolated from any previous builds.
variables:
  GRADLE_OPTS: "-Dorg.gradle.daemon=false"

before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle

build:
  stage: build
  script: gradle --build-cache assemble
  cache:
    key: "$CI_COMMIT_REF_NAME"
    policy: push
    paths:
      - build
      - .gradle

test:
  stage: test
  script: gradle check
  cache:
    key: "$CI_COMMIT_REF_NAME"
    policy: pull
    paths:
      - build
      - .gradle

Again, make sure this code is saved in a file called .gitlab-ci.yml (don’t forget that leading period!).

Before using CI, we need to check one more thing. Open the build.gradle file, located in the lib folder of your top-level project directory. Make sure to add version numbers of the Jupiter API and Engine if they are not already there:

We should now be ready to use GitLab’s CI tool to automatically run all unit tests every time the code is pushed – if any tests fail, the developer will even be notified by email.

Let’s give it a shot. Open your java class and add a comment at the bottom of the file. Then run git add ., git commit -m “Second commit”, and git push origin master.

If you navigate to the CI/CD tab on the left-hand side of GitLab and look at the pipeline, you will see the build and test commands running. If you have no errors, the status should change to passed. See the images below for a running pipeline versus a completed pipeline:

Running pipelines
Passed pipeline

Congratulations! Now every time you push changes to GitLab, all of your unit tests will be run. You have now implemented a simplistic version of automated unit testing on your own machine. I hope this has been a valuable insight to those getting started with testing automation.

Outside articles used:

https://www.testim.io/blog/what-is-test-automation/
https://medium.com/@jonashavers/how-to-use-junit-5-with-gradle-fb7c5c3286cc
https://www.qaautomation.co.in/2019/07/introduction-to-gradle-beginners-guide.html

From the blog CS@Worcester – Christian Shadis' Blog by ctshadis and used with permission of the author. All other rights reserved by the author.

Blog Post 1: Importance of Quality Assurance

Software development isn’t all about writing code. A vital aspect of software development is quality assurance. Some may think that quality assurance is just all about testing the code to make sure it works. However, while that is a big part of quality assurance, there is more to it than that. As the name itself suggests, a quality assurance team ensures that the development of a product goes smoothly and without flaws. Testing occurs during each phase of development. They confirm that the end product is properly working before it releases.

Now of course sometimes you can’t have a whole team to certify that your code is perfect. Learning how to do QA on your own code is helpful as a programmer. This could include writing tests for your code, as well as making sure the code does not have anything unnecessary. Although this type of testing may not be an extensive as real Quality Assurance testing, it is still a good way to make sure that the program can run smoothly. There are many different forms of testing, some of which may be automated. Some developers feel that writing up tests for their code may take up more time than it is worth, so automation is an optimal solution.

Having quality assurance in software development increases the quality of the code and results in a more finished end product. It is an essential aspect of creating up to par software, and so being able to provide quality assurance to their code is something that every programmer should strive for.

Articles that provided useful information about quality assurance:

https://www.altexsoft.com/whitepapers/quality-assurance-quality-control-and-testing-the-basics-of-software-quality-management/

https://fortegrp.com/why-qa-is-essential-to-delivery-team/

From the blog CS@Worcester – CSBlogger by mjaber54 and used with permission of the author. All other rights reserved by the author.

Software Quality Assurance and Testing Blog Post #1 (JUnit 5 Testing)

For my first reflective blog entry on my Software Quality Assurance and Testing class, I decided to further research Java JUnit 5 testing. JUnit 5 testing was the topic of my first assignment in this course, and a lot of the assignment involved researching. I wanted to do even more research now that I finished my assignment and record it as this blog post. One of the biggest takeaways from the assignment was learning the differences between JUnit 5 and JUnit 4 to see why we use JUnit 5 now. I decided to find a good source on the differences and discuss them here. The best source that I found was from HowToDoInJava.com, and this website was actually one that I referred to for help on my assignment earlier. The source describes eight major differences. The first change from JUnit 4 to JUnit 5 is the change in annotations. Many syntax changes occur when switching to JUnit 5 (not every one changes). Next, it discusses the architecture which changes from one single jar file to three separate sub-projects (Platform, Jupiter, and Vintage). The SDK version requirements change from one to another as well as assertions and assumptions slightly differ as well. Test Suites and tagging both change as well. Lastly, JUnit 5 finally allows for third party integration while JUnit 4 never did. Most of these changes are not game-changing or extremely different from each other, but all combined manage to prove that JUnit 5 is a step forward from JUnit 4. I am happy that we went over this topic as an assignment in my course because I did not even know that JUnit had separate versions like this until now! If I were you, I would definitely give my source for this blog post a read. It was very interesting, and it did a great job explaining the differences I was trying to uncover! I will put a link to it at the conclusion of this post.

https://howtodoinjava.com/junit5/junit-5-vs-junit-4/

From the blog CS@Worcester – Tim Drevitch CS Blog by timdrevitch and used with permission of the author. All other rights reserved by the author.

Testing With JUnit 5

Photo by Markus Spiske on Pexels.com

Recently I was introduced to JUnit 5 as a testing framework for Java programs, mainly for the purposes of one of the courses I am taking currently. While I have in the past used methods such as print statements (to test for expected outputs and debug) or using the built-in IDE debugging functions (breakpoints mainly), this was often time-consuming and not easy to scale. When trying to test for a number of different conditions or desired results from a section of the program, I would often end up writing conditional logic just for testing purposes which would end up getting deleted later on in the finished program.

JUnit seems like a relatively logical progression from this process, instead of writing numerous checks and conditional statements into the working code of the program, test classes can be used to rapidly test many different conditions or input/outputs at once. This allows for me to keep the main code of the program neater and to avoid the time consuming process of having to continually write tests or print out values in order to test that everything is functioning properly. JUnit overall is a more efficient way to go about the process.

In the past, I had used an older version of JUnit (JUnit 4) to test an older project from a number of years ago. I found this blog post from Java Magazine (https://blogs.oracle.com/javamagazine/migrating-from-junit-4-to-junit-5-important-differences-and-benefits) was able to highlight many of the major changes and differences between JUnit versions 4 and 5 clearly. Generally, JUnit 5 differs the most in it’s organization into various modules, while older versions of the framework would include all features irregardless of which ones might actually be needed at the time.

Additionally, more recent Java features such as lambda functions (absolutely useful within the context of running tests) make this version of JUnit more powerful than earlier editions.

I would consider JUnit 5 to be one of the better options at present for testing and debugging Java programs and will likely continue to utilize this framework until it inevitably sees a version 6 release.

Article Referenced: https://blogs.oracle.com/javamagazine/migrating-from-junit-4-to-junit-5-important-differences-and-benefits

From the blog CS@Worcester – CodeRoad by toomeymatt1515 and used with permission of the author. All other rights reserved by the author.

Blog Post #1: JUnit 4 vs JUnit 5

For my first post, I got the idea to look more into the differences between JUnit 4 and 5 after the video and questions from the first Advanced Assignment for CS-443.

JUnit 4 was first released in 2006, and was the prior main framework for Java developers. 4 built upon assertions and annotations for methods and testing, and was used for over a decade. However, a big change was needed because of growing issues with JUnit 4 with modularity and extensions. This big change came in the form of JUnit 5.

JUnit 5 was then released in 2017, and JUnit 5 is meant to improve on JUnit 4, so it has multiple advantages over the latter framework, such as:

  • Divided into three bundles: Platform, Jupiter, and Vintage, instead of being a single jar file.
  • With JUnit 5, you can import what is necessary, while JUnit 4 imports the whole library.
  • Multiple test runners can run at a time on JUnit 5, while JUnit 4 only allows one at a time.
  • Additional annotations, such as annotations for nested loops and custom extensions
  • Lambda expressions
  • JUnit 5 uses Java 8 and higher, while JUnit 4 stops at Java 7.

JUnit 5 is the main framework that is used today for Java, and continues to get updated to this day. JUnit 4 was efficient for many years, but JUnit 5 is the better framework by improving on 4s flaws and continuing to improve as time goes on.

https://howtodoinjava.com/junit5/junit-5-vs-junit-4/

https://blogs.oracle.com/javamagazine/migrating-from-junit-4-to-junit-5-important-differences-and-benefits

https://www.baeldung.com/junit-5-migration

From the blog Jeffery Neal's Blog by jneal44 and used with permission of the author. All other rights reserved by the author.

Software QA Log #1: Understanding Quality Assurance

Even though we don’t consciously think about this fact, many products that we use in our daily lives are made with particular specifications and go through rigorous testing and quality assurance before they are put out for public use. Regardless of the complexity, every product that we use is expected to go through particular standardized procedures that will ensure that the product can fulfill certain specifications before it is put out for any kind of use. Essentially, everything created that is meant for use goes through the process of Quality Assurance (QA) and Quality Control (QC) in order to ensure that quality specifications are met and that the end result of a product is satisfactory.

Components of computer systems, specifically software (as it is the focus of this blog), are among those products that go through the process of QA and QC testing before they are released to the end consumers in order to ensure that quality specifications are met and that the products released are the best that they can possibly be in regards to performance, security, and whatnot. Essentially, QA and QC testing in regards to software are what separate a good product of code from a defective code of lesser quality. Though both QA and QC testing are important parts of software development, it is important to properly define each terms and to make a distinction between the two. Though I will be using this blog to discuss Software Quality Assurance Testing specifically, I believe it would be helpful to understand the distinctions between Quality Assurance and Quality Control.

In software engineering, quality assurance is a set of standardized procedures whose aim is to ensure that certain specifications of quality are being met during development, therefore making this process a core part of software development. On the contrary, quality control is a process of software engineering which evaluates the quality of the end product, meaning that this process occurs after development and before a product is distributed rather than alongside it. While both processes make sure that quality standards of software are met, their difference lies on which part of development they typically occur in. Moreover, in the context of software development, QA ensures that certain defects, such as bugs, are properly taken care of during development, whereas QC might address less technical issues that could still impact the quality of the end product if left unaddressed and ensure that improvements to the end product are made accordingly.

There are multiple methods of QA Testing which may be divided into two types, functional and non-functional. Functional QA testing ensures that the software works as intended depending on the inputs or overall interactions an end user has with it. On the other hand, non-functional QA testing aims to conduct tests regarding (but not limited to):

  1. Vulnerability/Security: such testing ensures that there are no security risks that would result in the system the software was installed on to be compromised by any means (i.e. hacking, data leaks)
  2. Compatibility: such test ensures that the software is fully compatible with and can be implemented on the system it was created to run on.
  3. Usability: such test ensures that the software is intuitive and can be used by end users with minimal difficulty (i.e. user-friendly GUI)
  4. Performance: such test ensures that the software can work in a variety of situations on the system it is implemented on, along with making sure that it can operate within the system’s limitations

In order to make sure that software performs well on a functional level, it often goes through rigorous unit and integration testing, both of which are used to ensure that software can perform by examining how parts of code (i.e. functions) work both independently and in union. Though these kinds of functional testing may often be slow and repetitive, they can often help uncover bugs and glitches that may occur when software executes and can help resolving any defects much easier.

Quality assurance is (or should be for some) an integral part of software development. It is not simply enough to write code that can be compiled and executed without error. It is important, however, to ensure that the software that is being developed meets certain quality standards both on a functional and a non-functional aspect in order to create a competent piece of software.

Articles I read that discuss this post’s topic in greater depth:
1) https://www.tiempodev.com/blog/what-is-qa-in-software-testing/
2)https://mycrowd.com/blog/what-qa-testing-methodologies-are-there/
3)https://www.thebalancesmb.com/definition-of-quality-assurance-2533665

From the blog CS@Worcester – CompSci Log by sohoda and used with permission of the author. All other rights reserved by the author.