Category Archives: CS-443

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.

A Start to Something Different

Hello. I don’t really know how you got here but welcome to my blog. I don’t really blog but I guess I will have to start somewhere, so I might as well start here. I started this blog for a class I was taking in my Senior Year of college, so at least initially, most of my posts will be responses to assignments from that class. At the moment, I don’t know what direction I want to take this blog but I hope you will consider coming back to this page one day to see how far I have gotten.

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.

Introduction

Hello everyone! I am Jeffery Neal and this is my first blog post. I am a Junior in Computer Science and enrolled in CS-443. I look forward to the rest of this semester!

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

New Semester Introduction

I am thrilled to be continuing the blogs I started in my previous semester. I’d like to introduce myself a little bit again in case anyone reading this is new to my blogs. For starters, I am a Computer Science major at Worcester State University, and I am scheduled to graduate in the Spring of 2021 (after this last semester). I have a concentration in Software Development and a minor in Mathematics. Outside of school, I like to play games, hang out with friends and family, and play sports. I am on the NCAA Ice Hockey team for Worcester State, but before college, I played many other sports like lacrosse and soccer. I graduated from Warren Hills Regional High School in New Jersey in 2017 before joining the WSU Lancers. I either plan to go to grad school or find a job after this semester! Most blogs following this will relate to two of my classes this semester (CS-443 and CS-448).

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.

Introduction

Hello! This is my first post on this blog. My name is Grace Ciampa, and I am a Computer Science major at Worcester State University. I am currently in my junior year, and I am hoping to graduate next spring. This blog will be focused mostly on coursework. I am looking forward to the rest of the semester.

From the blog CS@Worcester – Ciampa's Computer Science Blog by graceciampa and used with permission of the author. All other rights reserved by the author.