Category Archives: CS-443

Software Testing Life Cycle

            I was interested in learning more about how software testing works in the professional world on a software development team. Since we are learning about the crafting of software tests in our class, I thought it would be interesting to learn how the pieces are put together, like how developing requirements goes into crafting tests and then executing them. It’s an essential part of a software development team, of course, and I’m sure I’ll be doing plenty of it in my future. I found this resource: https://www.tutorialspoint.com/stlc/stlc_overview.htm from Tutorials Point that gave an overview of the “Software Testing Life Cycle” (STLC) which help put the pieces together for me.

            First, what is the STLC? It deals strictly with testing and “starts as soon as requirements are defined… by stakeholders.” Sidenote, this reminds me of test-driven development, which, by my understanding, is a common practice in software development these days. The STLC consists of 7 parts. The first is requirement analysis, at which point the team analyzes the application under test (AUT) at a high level. Then comes test planning where a strategy for testing is devised. Then is test case designing which is applying the requirements and making tests according to the planning. Then is the test environment setup for integrated testing. This is the last step before actual testing. Next is test execution which yields defect reporting. This either validates tests or finds bugs. Last is test closure, where testing is finished and matrix, reports, and results are completed.

            This was great to see the pieces come together. This very basic overview helps me see what working on software testing in the professional world would be like. Seeing a timeline also provides context for some of the things we’ve been learning in class.

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

Boundary Value Analysis and Equivalence Partitioning Testing

When it comes to a large pool of input data, it is not possible to perform exhausting testing for each set of test data. There should be an easy way to select test cases from the pool so that all scenarios are covered. This is when the Equivalence Partitioning & Boundary Value Analysis testing techniques were introduced. In today’s blog, I want to do further research on the testing technique of Boundary Value Analysis and Equivalence Partitioning Testing. Equivalence Partitioning and Boundary value analysis are linked to each other and can be used together at all levels of software testing. To start, Boundary value testing is the process of testing between extreme boundaries between the partitions, for example like start, end, lower, upper, maximum, minimum, just inside, and outside values. Normally Boundary value analysis is part of stress and negative testing. Using the Boundary Value Analysis technique tester creates test cases for the required input field.

Now when it comes to equivalence partitioning or equivalence class testing is a type of black box testing technique in which the input data units are divided into equivalent partitions that can be used to derive test cases. This helps with reducing the time required for testing a small number of test cases. This technique can be applied to all levels of software testing like system, unit, and integration. One of the examples that were widely used in many resources that I have look at is: let us say a password field accepts a minimum of 6 characters and a maximum of 10 characters, that means results for values in partitions 0-5, 6-10, 11-14 should be equivalent.  The three testing scenarios will be:

1       Enter 0 to 5 characters         System should not accept

2       Enter 6 to 10 characters       System should accept

3       Enter 11-to-14-character      System should not accept.

Equally, Both testing techniques are used to reduce a very large number of test cases to a manageable piece, Both are appropriate for calculating intensive applications with such a large number of variables and input data.

https://www.guru99.com/equivalence-partitioning-boundary-value-analysis.html

https://www.softwaretestingclass.com/boundary-value-analysis-and-equivalence-class-partitioning-with-simple-example/

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

The Power of Decision Table Testing

In POGIL activity 8, we worked with decision table-based testing and applied it to applied this concept to the ongoing graduation problem. Unlike the previous activities, we did not go over the advantages of using a decision table opposed to using any of the other testing frameworks. So for this blog post, I want to look more at the pros of using decision table-based testing.

In this article, it gives a complete step-by-step rundown of what is a decision table, why we use it for testing and how to conduct decision table-based tests.

It is basically a review of what we covered in class with pictures/diagrams at each step.

In this second article, it talks about the characteristics of decision tables and why some of these characteristics may make decision table-based testing more preferable to the other testing frameworks.

https://www.edureka.co/blog/decision-table-in-software-testing/#advantages

Decision table-based testing is similar to Equivalence Class testing in the sense that it divides the tests into cases and complete test coverage. Unlike Equivalence Class testing, decision tables are more versatile. One aspect that I really liked about this second article was the fact the author completed multiple action rows into just one rule by defining a key. This made the table smaller and easier to read while not obscuring the meaning within the table.

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.

Boundary Value Testing and Equivalence Class Testing

Due to their being a large capacity of data that is used for software, there needs to be test implementation that can test the range of values without testing each number. Therefore, we used testing methods such as boundary value testing and equivalence class testing. The purpose of boundary value testing is to test the extreme ends or also known boundaries hence the name. The most common way to implement this test case is to use input variable values such as a minimum value, a value just higher than minimum, a middle value none as the nominal, a value that is just lower than the maximum and the last is the maximum value. One common example that most have seen is when we have to set up a password. Let’s say that a valid number length for the password has to be between 10 and 15. Using this guide, our boundary value testing would consider values that are less than, ones that are 10, ones that are between 10 and 15, ones that are 12 and ones that are greater than 15. Now the valid inputs will be passwords that are between 10 and 15 and so boundary value testing implementations are a good way to test any input errors that are more near the boundaries of valid numbers.

Equivalence class testing is a method of testing that divides the input of the data into various different equivalence classes. This step is the partitioning of the values that need to be tested and is the step that comes before boundary testing. The accurate values that are considered acceptable inputs are divided into a certain range, and the values under as well as over are considered invalid or unacceptable to the software. The valid class partition keeps all the valid values or inputs in it and the invalid class partition contains the invalid values and partition. The example is same as the password one and how the password that in the acceptable range of 10 to 15 will be accepted and valid, whereas passwords that are less than 10 or more than 15 will be invalid and won’t be accepted. Overall, boundary and equivalence class testing are good testing implementations to test input values without having to try to test all the individual values.

Resources:

Boundary Value Analysis and Equivalence Class Partitioning With Simple Example

https://www.guru99.com/equivalence-partitioning-boundary-value-analysis.html

From the blog CS@Worcester – Roller Coaster Coding Journey by fbaig34 and used with permission of the author. All other rights reserved by the author.

Difference Between Black-Box, White-Box

 White-box or glass-box testing is testing from a program’s source code without using the user interface. This type of testing needs to look at code syntax to find flaws or errors in the internal code in algorithms, overflows, paths, conditions, and so on, and then fix them.

Black-box testing, or black-box testing, is rigorously tested by using the entire software or a software function without examining the source code of the program or having a clear understanding of how the program or the source code of a software function was designed. Testers understand how the software works by entering their data and seeing the results. Typically, testers run tests using not only input data that is guaranteed to give correct results but also input data that is challenging and may result in errors in order to understand how the software handles various types of data.

The program under test is treated as a black box, without considering the internal structure and characteristics of the program. The tester only knows the relationship between the input and output of the program or the function of the program and determines the test cases and inferences the correctness of the test results by relying on the requirement specifications that can reflect the relationship and function of the program.

Black box testing of software is used to verify the correctness and operability of software functions. Treat the program as a black box, without considering the internal structure of the program box processing. In the program interface test, just to check whether the program function in accordance with the specification of the normal use. Black box testing is also called functional testing or data-driven testing.

White-box testing is exhaustive path testing, and black-box testing is exhaustive input testing. These two methods are based on completely different points of view, reflecting the two extremes of things. They have their own emphasis and advantages, but they cannot replace each other. In the modern concept of testing, the two methods are not separate but intersect.

It relies on the careful examination of the details of the program, the design of test cases for specific conditions, and the testing of the logic path of the software. Check the “state of the program” at various points in the program to see if the actual state corresponds to the expected state. White-box testing of software is used to analyze the internal structure of a program.

sources:

Difference Between Black-Box, White-Box, and Grey-Box Testing

From the blog haorusong by and used with permission of the author. All other rights reserved by the author.

Static vs Dynamic Testing

Two common methods used for software testing are static and dynamic testing. Now, although they are both testing methods, there are a lot of differences between them. First we need to define what each of them are. Static testing is when we test the software to look for errors or defects, but we are not going to actually execute the code. Now on the other hand, for dynamic testing we test the software by executing the code and see if there is any errors with inputs and overall function of the software. Static testing is conducted with specific documents related to the software and the goal is to find errors early on in the development cycle before the software gets too advanced. Dynamic testing executes the code and analyzes things such as the input and output of the software to determine the correct results. The goal for dynamic is to test the functional behavior of the code and also takes into account memory, CPU as well as the performance of the software put together. Static testing uses manual or automated testing of the documents by examining things such as the requirements for the software, the source, necessary test cases or any thing related to the overall design. Dynamic testing is more direct testing to whether the software works by using techniques such as black or white box testing and it confirms that the code works in the way it is desired to.

The main differences between static and dynamic is one thing we stated earlier about how static won’t be executed, whereas dynamic will. Another important factors is the stages with where these tests occur, as static happens early in the process of developing software, whereas dynamic is towards the end or completion stage. The goal of static testing is to prevent any bugs or errors from being produces, but dynamic tests finds bugs or errors that were created with the development of the software. Static testing is more simply known as the verification process, whereas dynamic testing is more about the validation process. Static testing is known to generally take shorter time, whereas dynamic will take a little bit longer due to the variance of test cases that need to be implemented. Overall, both of these testing methods are important in the development of software, but they occur at different stages and can be helpful to do both efficiently to lead to the least amount of error in the software.

Resources:

https://www.geeksforgeeks.org/difference-between-static-and-dynamic-testing/ https://www.guru99.com/static-dynamic-testing.html

From the blog CS@Worcester – Roller Coaster Coding Journey by fbaig34 and used with permission of the author. All other rights reserved by the author.

Boundary Value and Equivalence Class Testing

This week in the Software Quality Assur&Test class we got the third assignment that was about Boundary Values and Equivalence Class Testing. We had worked during class time in different activities that covered this assignment so I would say I really enjoyed working in this assignment. We had to complete three parts each with a different level of difficulty. I learned to understand more of the way testing works and what exactly get tested.

What we covered in this homework:

Boundary testing is the process of testing between extreme ends or boundaries between partitions of the input values.

Robust Boundary Values. Introducing outside of boundary values.

Equivalence Class Testing, which is also known as Equivalence Class Partitioning (ECP) and Equivalence Partitioning, is an important software testing technique used by the team of testers for grouping and partitioning of the test input data, which is then used for the purpose of testing the software product into a number of different classes.

Weak Normal Equivalence Class Testing: In this first type of equivalence class testing, one variable from each equivalence class is tested by the team. Moreover, the values are identified in a systematic manner. Weak normal equivalence class testing is also known as single fault assumption.

Strong Normal Equivalence Class Testing: Termed as multiple fault assumption, in strong normal equivalence class testing the team selects test cases from each element of the Cartesian product of the equivalence. This ensures the notion of completeness in testing, as it covers all equivalence classes and offers the team one of each possible combinations of inputs.

Worst-Case boundary value analysis is a Black Box software testing technique.

In Worst case boundary value testing, we make all combinations of each value of one variable with each value of another variable.

Edge Testing is a combination of Boundary Value Analysis and Equivalence Class Testing.

Weak Robust Equivalence Class Testing: Like weak normal equivalence, weak robust testing too tests one variable from each equivalence class. However, unlike the former method, it is also focused on testing test cases for invalid values.

Strong Robust Equivalence Class Testing: Another type of equivalence class testing, strong robust testing produces test cases for all valid and invalid elements of the product of the equivalence class. However, it is incapable of reducing the redundancy in testing.

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

The Best of Both Worlds: Edge Testing over Boundary-Value Testing or Equivalence Partition Testing

Christian Shadis

Self-Directed Blog Post #3

Two common testing techniques in Black-Box Software Testing are Boundary Value Testing (or Boundary Value Analysis) or Equivalence Partition Testing (or Equivalence Class Testing). Both techniques examine the output of a program given its inputs.

Consider a function eligibleForScholarship which accepts two inputs, SAT score (for simplicity, only considering 1600 scale) and GPA (on a 4.0 scale) and returns in dollars the total reward a student is eligible to receive. At CompUniversity, a student will receive a scholarship if their SAT score is at least 1200 and their GPA is at least 3.5. The amount of that scholarship is determined by the criteria in the table below.

SAT Score SAT Score Award
0-1199 $0
1200-1399 $1000
1400-1600 $2500

In addition to the SAT reward, additional money is given based on GPA.

GPA % of SAT award earned
0-3.49 0%
3.5-3.74 100%
3.75-3.89 120%
3.90-4.0 150%

For example, a student with an SAT score of 1450 and GPA of 3.8 will receive $2500 plus an additional 20% for a total of $3000. A student with an SAT score of 1600 and a GPA of 3.49 will receive $0.

If software tester wanted to write test bases based on Robust Boundary Value Analysis, they would arrive at the following set of test cases:

Boundaries:
SAT Score upper bound: 1600 (physical limit)
SAT Score lower bound: 0 (physical limit)
GPA upper bound: 4.00 (physical limit)
GPA lower bound: 0.00 (physical limit)

Test Case SAT Score GPA Expected Output
1 <x1min-, x2nom> -1 3.50 Exception
2 <x1min, x2nom> 0 3.50 0
3 <x1min+, x2nom> 1 3.50 0
4 <x1max-, x2nom> 1599 3.50 2500
5 <x1max, x2nom> 1600 3.50 2500
6 <x1max+, x2nom> 1601 3.50 Exception
7 <x1nom, x2nom> 1200 3.50 1000
8 <x1nom, x2min-> 1200 -0.01 Exception
9 <x1nom, x2min> 1200 0.00 0
10 <x1nom, x2min+> 1200 0.01 0
11 <x1nom, x2max-> 1200 3.99 1500
12 <x1nom, x2max> 1200 4.00 1500
13 <x1nom, x2max+> 1200 4.01 Exception

Disadvantages of Boundary Value Testing:
There are possible outputs that this set of test cases never checks (e.g. $3000, $3750). Additionally, this set of test cases fails to test the behavior inside the program, instead focusing on outermost limits.

If the software tester instead wanted to write test cases based off of Strong Normal Equivalence Partitioning, they would arrive at the following set of test cases:

Test Case SAT Score GPA Expected Output ($)
1 (0 <= sat < 1200, 0 <= gpa < 3.50) 1000 2.0 0
2 (1200 <= sat < 1400, 0 <= gpa < 3.50) 1300 2.0 0
3 (1400 <= sat <= 1600, 0 <= gpa < 3.50) 1500 2.0 0
4 (0 <= sat < 1200, 3.50 <= gpa < 3.75) 1000 3.6 0
5 (1200 <= sat < 1400, 3.50 <= gpa < 3.75) 1300 3.6 1000
6 (1400 <= sat <= 1600, 3.50 <= gpa < 3.75) 1500 3.6 2500
7 (0 <= sat < 1200, 3.75 <= gpa < 3.90) 1000 3.8 0
8 (1200 <= sat < 1400, 3.75 <= gpa < 3.90) 1300 3.8 1200
9 (1400 <= sat <= 1600, 3.75 <= gpa < 3.90) 1500 3.8 3000
10 (0 <= sat < 1200, 3.90 <= gpa <= 4.00) 1000 3.95 0
11 (1200 <= sat < 1400, 3.90 <= gpa < 4.00) 1300 3.95 1500
12 (1400 <= sat <= 1600, 3.90 <= gpa < 4.00) 1500 3.95 3750

Disadvantages of Equivalence Partitioning:
This set of test cases does not successfully account for behavior at the boundaries of valid inputs, nor does it account for the behavior of the program with every possible combination of inputs.

The disadvantages of boundary value testing and equivalence partitioning can be addressed by instead implementing edge testing.

Edge Testing

In Edge testing, we want to examine any point at which behavior changes, and create test cases for all of those ‘boundaries’, along with values close to the boundaries on either side.

The SAT edge cases can be listed as {-1, 0, 1, 1199, 1200, 1201, 1399, 1400, 1401, 1599, 1600, 1601}.
The GPA edge cases can be listed as {-0.01, 0.00, 0.01, 3.49, 3.50, 3.51, 3.74, 3.75, 3.76, 3.89, 3.90, 3.91, 3.99, 4.00, 4.01}.

Test cases can now be created by taking all pairwise combinations of edge cases (Worst-case). There are too many test cases to list here without taking up unnecessary space, but now our tests account for each and every possible combination of inputs.

Edge testing combines the best attributes from Boundary Value testing and Equivalence Partitioning into one comprehensive technique. Edge testing successfully tests the upper and lower bounds for each input, and it successfully examining inner behavior at each partition.

Edge testing has a major drawback: the number of test cases needed. In this example, there are 12 * 15 = 180 test cases, but it has unrivaled behavior coverage. The decision of which testing technique to use depends largely on the program for which the tests are being developed, but for a smaller number of partitions in the inputs, edge testing is a relatively simple but comprehensive technique for testing all possible behavior.

Articles used for my research:
https://professionalqa.com/equivalence-class-testing
https://artoftesting.com/boundary-value-analysis
https://www.mindfulqa.com/edge-cases/
Class materials from CS-443 at Worcester State University

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

Black-Box vs. White-Box Testing

In class, we have been learning about the different types of testing methods. Today I want to focus on Black-Box vs. White-Box testing. Let us start by looking at how each test method differs from the other. Black Box testing is a software method in which the internal structure design and implementation of the item being tested are not known to the tester. However, in white box testing, the internal structure, design, and implementation are known to the tester.

Let us start by looking at a diagram example that was provided in one of my resources for black-box testing. The picture above of Black Box testing can be any software system. For example, a website like a google or an amazon database. All under the Black Box testing, you can test the applications by just focusing on the inputs and outputs without knowing their internal code implementation. There are many types of black box testing methods, but the main types are functional, nonfunctional and regression testing.  Now let us look at some of the techniques used in black-box testing. The few main ones are Equivalence class testing, boundary value testing, and decision table testing. I know we went over these in-depth in class, but I had no idea that these were related to black-box testing.

Now unlike Black Box testing, white box testing requires the Knowledge of the implementation to carry out. One of the main goals of white-box testing is to very a working flow for an application. It mainly involves testing a series of inputs against expected or desired output so that when the results in the expected output do not match with the input you have encountered a bug. One of the main techniques that are used in White-Box testing is code coverage analysis, which eliminates any gaps in the test case suite. These tests can be easily automated. While researching some of the disadvantages I found out was that white boxing can be quite complex and expensive. It also can be very time-consuming due to bigger applications taking time to test fully. Overall, both testing methods are important and necessary for successful software delivery.

https://www.geeksforgeeks.org/differences-between-black-box-testing-vs-white-box-testing/

https://www.guru99.com/black-box-testing.html

https://www.guru99.com/white-box-testing.html

From the blog Derin&#039;s CS Journey by and used with permission of the author. All other rights reserved by the author.

Implementing Boundary-Value Testing and Equivalence Partitioning in JUnit 5

By Christian Shadis

CS-443 Self-Directed Blog Post #2

In this post, I will compare the implementations of Robust Boundary Value Testing and Equivalence Partitioning using simple examples and actual JUnit code.

For the purposes of this post, you have been elected ChairBee of HoneyComb Council in your neighborhood’s local beehive. Your main job is to determine whether a worker bee has produced enough honey to retire. There are two criteria by which you base your decision, age and number of flowers pollinated. As a bee, your brain was incapable of making this complex of a decision every time a bee requests retirement, so you decided to write a Java program to do the heavy lifting for you.

Your function needs two inputs: the number of flowers pollinated, and the age of the bee in days. Your decision is based on these conditions: A bee is eligible to retire at age 18, but only if they have pollinated at least 20 flowers.

boolean readyToRetire(int age, int flowersPollinated) throws IllegalArgumentException{

   if(age < 0 || age > 50)
      throw new IllegalArgumentException();
   if(flowersPollinated < 0 || flowersPollinated > 200)
      throw new IllegalArgumentException();
   if(age >= 18 && age <= 50) {
      if(flowersPollinated < 20) 
         return false;
      else
         return true;
   }

   else
      return false;
}

Being the good little former working bee you are, you decide that no program is worth its weight in beetles (joke of an insect, really) if it doesn’t have a JUnit Test Suite to go along with it. You decide that you want to develop test cases with one of two methods: Boundary Value Testing or Equivalence Partitioning.

Boundary Value Testing

There are physical and arbitrary limits implemented on each input of the function. The age of a bee, obviously, cannot be a negative number, and for a creature with a life expectancy of 28 days, you cannot expect it to live past 50 days. Our acceptable inputs for age are 0 <= age <= 50. Likewise, a negative number of flowers being pollinated is impossible, and a bee in our hive is extremely unlikely to pollinate close to 150 flowers, let alone 200. Our acceptable inputs for flowers pollinated are 0 <= flowers <= 200. Thus, we implement a physical limit of 0 to both age and flowers pollinated, and arbitrary upper limits of 50 and 200, respectively.

In Robust Boundary Value testing, we take each boundary of an input, and one step in the positive and negative directions, and test each against the nominal (or ideal) value of the other input. We arrive at the following test cases:

Test Case Age Flowers Pollinated Expected Output
1 <x1min-, x2nom> -1 30 Exception
2 <x1min, x2nom> 0 30 False
3 <x1min+, x2nom> 1 30 False
4 <x1max-, x2nom> 49 30 True
5 <x1max, x2nom> 50 30 True
6 <x1max+, x2nom> 51 30 Exception
7 <x1nom, x2nom> 20 30 True
8 <x1nom, x2min-> 20 -1 Exception
9 <x1nom, x2min> 20 0 False
10 <x1nom, x2min+> 20 1 False
11 <x1nom, x2max-> 20 199 True
12 <x1nom, x2max> 20 200 True
13 <x1nom, x2max+> 20 201 Exception

Now we write JUnit 5 Test cases for each row in the table above. We will assume the readyToRetire function is inside a Bee class.

@Test
void test1(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(-1, 30); } );
}

@Test
void test2(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(0, 30);
   assertFalse(result);
}

@Test
void test3(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(1, 30);
   assertFalse(result);
}

@Test
void test4(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(49, 30);
   assertTrue(result);
}

@Test
void test5(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(50, 30);
   assertTrue(result);
}

@Test
void test6(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(51, 30); } );
}

@Test
void test7(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 30);
   assertTrue(result);
}

@Test
void test8(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(20, -1); } );
}

@Test
void test9(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 0);
   assertFalse(result);
}

@Test
void test10(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 1);
   assertFalse(result);
}

@Test
void test11(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 199);
   assertTrue(result);
}

@Test
void test12(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 200);
   assertTrue(result);
}

@Test
void test13(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(20, 201); } );
}

Equivalence Class Partitioning

Equivalence class partitioning arises from the foundational concept that with this function, there will be one of three results. An Exception will be thrown, true will be returned, or false will be returned. Based on our information about the criteria for deciding if a bee can retire, the behavior of the function can be modeled with a table.

age > 50 E E E E
18 <= age <= 50 E False True E
0 <= age < 18 E False False E
age < 0 E E E E
FP < 0 0 <= FP < 20 20 <= FP <= 200 FP > 200

Each cell in this table is an equivalence class and can represent a test case in the JUnit Test Suite. With your bee work ethic, you decide to implement Strong Robust Equivalence Testing, which is the most thorough method, and uses every cell in the table above as a test case.

Test Case Age Flowers Pollinated Expected Output
1 (age > 50, FP < 0) 51 -1 Exception
2 (18 <= age <= 50, FP < 0) 20 -1 Exception
3 (0 <= age < 18, FP < 0) 15 -1 Exception
4 (age < 0, FP < 0) -1 -1 Exception
5 (age > 50, 0 <= FP < 20) 51 10 Exception
6 (18 <= age <= 50, 0 <= FP < 20) 20 10 False
7 (0 <= age < 18, 0 <= FP < 20) 15 10 False
8 (age < 0, 0 <= FP < 20) -1 10 Exception
9 (age > 50, 20 <= FP <= 200) 51 30 Exception
10 (18 <= age <= 50, 20 <= FP <= 200) 20 30 True
11 (0 <= age < 18, 20 <= FP <= 200) 15 30 False
12 (age < 0, 20 <= FP <= 200) -1 30 Exception
13 (age > 50, FP > 200) 51 201 Exception
14 (18 <= age <= 50, FP > 200 ) 20 201 Exception
15 (0 <= age < 18, FP > 200 ) 15 201 Exception
16 (age < 0, FP > 200 ) -1 201 Exception
@Test
void test1(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(51, -1); } );
}

@Test
void test2(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(20, -1); } );
}

@Test
void test3(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(15, -1); } );
}

@Test
void test4(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(-1, -1); } );
}

@Test
void test5(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(51, 10); } );
}

@Test
void test6(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 10);
   assertFalse(result);
}

@Test
void test7(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(15, 10);
   assertFalse(result);
}

@Test
void test8(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(-1, 10); } );
}

@Test
void test9(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(51, 30); } );
}


@Test
void test10(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(20, 30);
   assertTrue(result);
}

@Test
void test11(){
   Bee testBee = new Bee();
   boolean result = testBee.readyToRetire(15, 30);
   assertFalse(result);
}

@Test
void test12(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(-1, 30); } );
}

@Test
void test13(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(51, 201); } );
}

@Test
void test14(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(20, 201); } );
}

@Test
void test15(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(15, 201); } );
}

@Test
void test16(){
   Bee testBee = new Bee();
   assertThrows(IllegalArgumentException.class, 
               () -> { testBee.readyToRetire(-1, 201); } );
}

Conclusion

We now have JUnit 5 Test Suites for both testing methods (boundary value testing and equivalence class testing). You are now prepared to serve your term as ChairBee knowing every decision will be made correctly, and having peace of mind that your test cases verified all desired behavior.

Equivalence class testing, at least with examples like this one, is a more thorough and robust technique that tests the programs behaviors as well as its input bounds, whereas boundary value testing focuses only on the extremes for each input. Each technique has its pros and cons, but I hope this simple example shed some light on implementing the theory behind boundary-value testing and equivalence class testing in JUnit 5.

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