Category Archives: Week 6

The White Belt

In this week’s blog post, I will be discussing the “The White Belt” pattern discussed in chapter 2 of “Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman” by Dave Hoover and Adewale Oshineye. This week, I chose this topic for my blog post because I think being able to set aside what you have learned in order to learn more is a difficult but important skill.

A quote early into this section that I can personally relate to discusses how your confidence in what you have already learned can cause you to have a harder time learning more. “You are struggling to learn new things, and it seems somehow harder than it was before to acquire new skills. The pace of your self-education seems to be slowing down despite your best efforts. You fear that your personal development may have stalled.” I have been in this position myself more than once. One approach the chapter mentions is called the not knowing stance.

The not-knowing stance, as mentioned in the chapter, is an approach to understanding that you do not and can not currently understand the entirety of what you are trying to accomplish. “Part of the approach Dave took as a family therapist included maintaining a not-knowing stance. Families in difficult circumstances were experiencing a unique reality that, despite his training, Dave knew he could not fully appreciate. While he acknowledged his skills at facilitating constructive questions and conversations, Dave was taught to refrain from believing that he had any expert knowledge into the realities that these families experienced. While this may seem counterintuitive, in reality, it fosters an attitude of respect and curiosity that opens up unforeseen possibilities and solutions. Rather than pushing solutions down on the family, Dave’s not knowing stance helped him to collaborate with the family to find solutions as a team.” As shown in this quote, embracing the not-knowing stance, can help you have a more open mind in trying to solve problems, or learn new things in different ways. Embracing the not-knowing stance is not only incredibly helpful in being able to learn new things, but can also help interpersonally, as shown by the quote.

From the blog CS@Worcester – P. McManus Worcester State CS Blog by patrickmcmanus1 and used with permission of the author. All other rights reserved by the author.

Equivalence Class Testing

Among various testing techniques, equivalence class testing stands out as an efficient method for cutting down the number of test cases required while maintaining thorough test coverage. 

Equivalence class testing is based on the principle that inputs can be grouped into equivalence classes that exhibit similar behavior. By selecting representative test cases from these classes, testers can efficiently cover various scenarios without testing every possible input value individually. This technique is the best of both worlds, optimizing test case selection all while maintaining thorough test coverage; as those from ProfessionalQA.com put it, both the quality of test cases as well as testing as a whole is enhanced “by removing the vast amount of redundancy and gaps that appear in the boundary value testing.”

Equivalence class testing has four variations, each of which have their own benefits, downsides, and uses. They are determined using the combinations of two factors, the number of test cases and whether only valid values are tested or both valid and invalid are tested Thus, in terms of equivalence classes, we have weak-normal, strong-normal, weak-robust, and strong-robust. Weak-normal has few but effective tests and only covers the valid equivalence classes, strong-normal covers every valid equivalence class, weak-robust is like weak-normal but includes an invalid equivalence class(es) as well, and strong-robust covers every valid and invalid equivalence class. One thing to note about strong-robust equivalence class testing is that there is some redundancy when it comes to testing the invalid equivalence classes.

Equivalence class testing was a bit hard to pick up initially but it really clicked thanks to some visual aid, that being the graphs of the variations of equivalence class testing. With this visual, I was able to understand how effective equivalence class testing is and why some will want to use it. It allows testers to “focus on smaller data sets, which increases the probability to uncovering more defects in the software product” and may reduce the possibility of error on the tester’s part. With other testing techniques that are more difficult or time-consuming when it comes to larger data sets, equivalence class testing is a great alternative.

https://www.professionalqa.com/equivalence-class-testing

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

Interesting Features of JUnit 5

Since beginning to work with code in CS443 – Software Quality Assurance and Testing, we’ve used JUnit framework for designing and running our test cases. So I decided to search for a blog post discussing some interesting features that I may not have come across yet, but could be useful and landed upon Exploring the Exciting New Features of JUnit 5. This post is from December 2023, so it should be relatively up-to-date and I recall a conversation with Dr. Wurst at one point where he briefly mentioned considering switching to a newer version of JUnit for some attractive features – hopefully we can delve into some of these.

Several feature additions come with JUnit 5 and specifically version 5.4. One that immediately stood out to me was support for more/new annotations and assertions like @Nested. We’ve looked at some basic annotations like @BeforeEach and @AfterAll in class but the idea of nesting tests is newer – however it makes perfect sense from a practical perspective. Depending on the outcome of an initial test, testers may want to run further tests on one branch or two different tests depending on which branch is followed. Proper annotating likely helps the compiler recognize the nested nature of the tests preceded and manage potentially complex webs of nested tests most efficiently.

There’s also improvements to the assertEquals() functions and overall flexibility through enhancements to API and insertion features for handling Lambda functions. This goes hand in hand with a new feature of JUnit 5 – the ability for tests to be dynamically generated during test runtime and implemented (if needed) using a Factory class/method. Last semester in Software Construction Design and Architecture, we learned about the Factory architecture and methodology so it was cool to see it applied to enhance features in professional software. 

Another cool feature of JUnit 5 which represents a considerable change from JUnit 4 is the transition to a modular structure, meaning there is a separate test runner and classes which operate independently from the main program. I could imagine that this separation isolates any issues that may arise during testing and protect the main program, while also preventing any unintended interactions with the main from interacting with properly designed tests.

JUnit 5 offers some major features and enhancements over the previous versions with the ability to tag and implement nested tests, improved Lambda function support and Factory method for dynamic test creation and implementation. Considering these, I can see how JUnit could be effective for designing automated test runs. I’m looking forward to implementing more of these features in our class and homework activities for CS443, and trying some extra tests and methods that I read about in this.

Source: 

https://blog.machinet.net/post/exploring-the-exciting-new-features-of-j-unit-5

From the blog CS@Worcester – Tech. Worth Talking About by jelbirt and used with permission of the author. All other rights reserved by the author.

Pairwise and Combinatorial Testing

The article “Combinatorial Testing” focuses on the insights of software testing methods. This article explores the evolution of combinatorial testing, talking about advancements in algorithm performance and constraint representation. The article also talks about the importance in detecting interaction failures within software systems. The article also demonstrates the effectiveness of t-way combinations fault detection across various domains. The article “Pairwise Testing” talks about pair testing as a permutation and combination technique aimed at testing each pair of input parameters to ensure that the system if functioning properly across all possible combinations. The article also addresses the many benefits of pairwise testing and it’s role in reducing test execution time and cost while maintaining test coverage. Also, it talks about the challenges associated with pairwise testing, including the limitations in detecting interactions beyond pairwise combinations.

Pairwise Testing

pairwise testing is a software testing method that aims to comprehensively validate the behavior of a system by testing all possible pairs of input parameters. This method is mainly used when many of the defects in software systems are triggered by interactions between pairs of input parameters, rather than by individual parameters in isolation.

Benefits & Challenges

some benefits that pairwise offers is, efficiency: by testing the combinations of two input parameters at a time. This reduce’s the number of test cases required compared to exhaustive testing. pairwise testing also offers effective defect detection: by effectively finding defects that are triggered by interactions between pairs of input parameters, pairwise testing also helps to identify certain scenarios by systematically exploring pairs of parameters. Some challenges that pairwise testing may face is when it comes to parameter selection. Selecting the right parameters is crucial and requires a lot of knowledge of the software and it’s potential interaction scenarios. If the wrong parameter is selected this can lead to incomplete test coverage and missed defects.

Combinatorial Testing

Combinatorial testing is a software testing technique that focuses on efficiently testing the interactions between different input parameters of a system. This test method involves generating a set of test cases that include various combinations of input values / specific parameter values.

Benefits & Challenges

Some benefits of combinational testing include improved software quality: by being able to identify and address the interaction failures early in the development process. This test method tests various combinations of input parameters, which can help find defects that could impact the systems performance. A challenge that combinational testing may face is the scalability. Combinatorial testing is effective for small to medium sized systems and when scaling it to large and complex systems with a high number of input parameters and values, you may run into some problems.

Why did I pick this Article?

I pick these two article that talk about pairwise and combinatorial testing because both these test methods stand at the forefront of software test methods. The article’s goes into details about how both of these test methods offer an efficient way to ensure comprehensive test coverage while minimizing redundancy. Both of these articles have taught me a lot about pairwise and combinational testing.

Reflection

After reading both of these articles, I have gained a greater understanding of both these test cases. With the new found knowledge, I aspire to apply pairwise and combinatorial testing techniques in my future projects. Both these test methods offer practical solutions to common testing challenges, and by incorporating them into my future endeavors I aim to contribute to the development of reliable software systems.

Article link is here: https://www.sciencedirect.com/science/article/abs/pii/S0065245815000352

https://testsigma.com/blog/pairwise-testing/

From the blog CS@Worcester – In's and Out's of Software Testing by Jaylon Brodie and used with permission of the author. All other rights reserved by the author.

Decision Table-Based Testing, a Game Changer for Software Bugs.

Today, the next meal on my menu of headaches is Decision Table-Based Testing, which as the name suggests is a table of tests to ensure that your software is working as intended and not printing “Hello World!” when you try to generate your salary. I may be downplaying it somewhat but the truth is that it might be one of the best weapons against bugs in software development.

Photo by Yan Krukau on Pexels.com

This approach is all about making sure your app or software doesn’t throw a tantrum under different situations by planning out every possible scenario in a neat, organized table. It’s a bit like planning a massive party and making sure you’ve thought of everything, so nothing goes wrong (well, almost nothing).

Imagine you’ve got a bunch of switches and dials that can be turned on, off, or dialed up to eleven. Decision tables help you figure out what happens to your software when you mess with those controls in every possible way. It’s a clear, visual way to lay out the “if this, then that” of your app’s behavior. This is very handy because it turns the headache of thinking through a million combinations of inputs and outcomes into something manageable.

What’s awesome about this is how it simplifies the chaos. You get this big-picture view of how different inputs play together and affect your software, making it easier to spot where things might go wrong. It’s like having a map when you’re in a maze, showing you all the paths you can take.

Starting to use Decision Table-Based Testing is pretty straightforward. You write down all the things that could change or affect your software (conditions) and what should happen in response (actions). Then, you mix and match these conditions to cover all your bases. This method is a fantastic way to find those sneaky bugs that only show up under specific conditions and to make sure your software is rock solid.

“But Ano, what if you update the app and add new stuff?”. As your app grows and gets more features, you can just update your decision table to keep up. It’s a flexible, scalable way to keep your testing game strong, no matter how advanced or complex your software gets.

Sure, it might sound a bit daunting, especially with super complicated apps. But, with the right tools and a bit of practice, it becomes a lot less scary. It’s about making the effort now to save a ton of headaches later when you’re not chasing down weird bugs half an hour before a project is due.

In the end, Decision Table-Based Testing is all about making your life easier and your software better. It’s a way to tackle the complexity head-on, with a clear plan and a cool head. And who doesn’t want that? So, if you’re in the business of making software, give it a whirl. It might just be the thing you need to keep those bug boogeymen at bay.

Till next time,

Ano out.

References:

https://testsigma.com/blog/decision-table-testing

https://www.guru99.com/decision-table-testing.html

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

Simplifying Software Testing: Decision Tables and Program Graphs

In the vast world of computer science, there are various techniques employed to ensure the reliability and efficiency of software systems. Two such techniques that play a crucial role in software testing are Decision Tables and Program Graphs. Let’s delve into what they are and how they contribute to the realm of computer science.

Decision Tables: Decision Tables are a systematic and structured way of representing complex decision-making processes. Imagine a scenario where a software program needs to make different decisions based on various conditions. These conditions can lead to different outcomes or actions. Decision Tables provide a visual representation of all possible combinations of conditions and their corresponding actions, making it easier to analyze and test different scenarios.

To understand Decision Tables better, think of a flowchart but with a more organized and concise format. Each column represents a condition, and each row represents a combination of conditions along with the corresponding action to be taken. By systematically analyzing all possible combinations, testers can ensure that the software behaves as expected under different circumstances.

Program Graphs: Program Graphs, on the other hand, offer a graphical representation of the control flow within a program. They depict how the program transitions from one state to another based on different inputs or conditions. Program Graphs help testers visualize the execution path of a program, identifying potential areas of concern such as loops, branches, or unreachable code segments.

These graphs aid in understanding the program’s behavior and facilitate the creation of comprehensive test cases to ensure thorough testing coverage. By traversing the program graph, testers can validate different paths and verify the correctness and robustness of the software.

DD Path Testing: DD Path Testing, short for Data Flow and Control Flow Path Testing, utilizes graphs to identify and test various paths through a program. It combines both data flow and control flow aspects to ensure comprehensive testing coverage. By analyzing the flow of data and control within the program, testers can identify potential vulnerabilities, errors, or inefficiencies.

By integrating Decision Tables, Program Graphs, and DD Path Testing into the software testing process, developers and testers can enhance the quality and reliability of software systems. These techniques enable thorough testing coverage, helping to identify and address potential issues early in the development lifecycle.

Here are two web links where you can find more information about Decision Tables, Program Graphs, and DD Path Testing:

  1. Decision Tables – Geeks for Geeks
  2. What is Graph in Data Structure & Types of Graph?

Talking about these topics is essential because they form the backbone of effective software testing strategies. By understanding and implementing these techniques, developers and testers can ensure that software systems meet the desired quality standards, resulting in enhanced user satisfaction and trust.

From the blog Discoveries in CS world by mgl1990 and used with permission of the author. All other rights reserved by the author.

spec based testing

As we move onto more code-based testing in class, I wanted to review some of the black box testing techniques we’ve gone over in class, especially since the most recent homework was somewhat confusing for me.

I’ll start off with boundary value testing. According to a blog post on SDET Unicorns, boundary value testing tests valid inputs in the domain (minimum, maximum, and one below and above them respectively), invalid inputs that are close to the domain, and any special inputs, such as empty strings or null pointers. This technique’s main use is testing boundaries, that is, it’s mostly concerned with whether or not invalid inputs are properly dealt with, and valid inputs are processed as valid. The drawback, as we discussed in class, is that it doesn’t really describe the different cases of valid inputs if there is branching taking place.

Equivalence class testing addresses this issue. From the same post above, equivalence class tests (or partitions, in the author’s words) divide inputs into, well, equivalence classes, or groups of input where behavior is expected to be the same. This also means that there are multiple groups of valid inputs, meaning this approach can effectively test different cases of valid inputs based on the specifications, rather than just testing if valid and invalid inputs behave as expected.

The reason why I wanted to look at these two specifically is because they are vital to understanding the decision table-based approach. I’m fairly confident in this approach because I found it fun to work with in class. It’s essentially a visualization and simplification of both boundary value and equivalence class testing, mostly equivalence class testing though, at least in my interpretation. The reason why I find it easier to work with decision tables is because they are much more efficient with regards to the space you use, even if the amount of mental work you have to do is larger.

It’s interesting because I found, in the homework at least, writing out test cases and the like for the non-table based approaches was somewhat frustrating because you have to consider each case even if they do the same thing, and write them out. With decision tables, you can optimize values into ‘dont cares,’ meaning that if the output is solely dependent on one of multiple inputs in this specific equivalence class, so you don’t have to care about what class the other values are. I really enjoy how this cleans up the entire process of black box testing. That being said, I understand that this can become very difficult to test as the complexity of a project increases.

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

Testing Paths

https://web.dev/articles/ta-test-cases

Last week, we tracked the path a program would take using program graphs. The program graph is good to represent the overall structure of a program; it shows all the ways the code can go. 

Afterwards, I wondered about the other types of paths a program could take, whether it be the best case, worst case, etc. That’s when I found Ramona Schwering’s article about test cases and happy paths.

Although I primarily read this article for it’s definitions and information on the different paths a software could provide, it also covers the idea of a test case and how to prioritize the right ones. Schwering first reminds us what a test case does whilst checking the results of the program: it verifies the program does what it’s intended to do, and it validates the program is what the customer or user wants. 

Next, Schwering explains what drew me to the article in the first place: test paths and their outcomes. The first path is known as the happy path, since it applies to the most common use case of your program; this is what should happen and what we want to happen. The second path is the scary path, which is used to catch errors and ugly outcomes. 

Schwering lists other test paths that aren’t used as frequently as the first two but could be important to recognize. I’ll talk about a few I find interesting.

  • An angry path is supposed to get an error; making sure error handling works.
  • A desolate path would be important for programs dealing with input data, as it tests to see if it’s given enough data to function correctly. 

Lastly, Schwering goes over the best practices for writing test cases, and how there are two patterns used to structure the cases: Arrange, act, assert and Given, when, then.

I selected this article because it covered my topic of interest and I also enjoyed Schwering’s straight to the point, easy to understand writing style. I decided to do a deeper dive on Schwering herself and found she’s a software developer and tester that speaks at international conferences worldwide. Reading through the post, I found the organization of the information to be helpful in my learning along with the information itself being reflective of my thoughts on our recent classes. 

The content Schwering provides in this article is great for a quick read for anyone wanting to learn more about testing. I personally believe the paths she went over are important to prioritize, especially happy and scary paths. I refreshed myself on the duties of a test case and learned multiple kinds of test paths, and how their importances varies from situation to situation. I enjoyed this article especially due to Schwering’s little illustrations and how easy it was to understand the paths. I hope to create test cases in the future with these paths in mind, using them to my advantage when possible.

From the blog CS@Worcester – Josh's Coding Journey by joshuafife and used with permission of the author. All other rights reserved by the author.

Testing Strategies

Once you learn to test your code, another thing you have to worry about is testing it as efficiently as possible. You can just write tests and hope that it ensures your code works effortlessly, but it may not always catch everything that can go wrong. Adopting some strategies and methods will be important in helping you determine how to go about testing your and managing that. 

There are a number of strategies that you can use and adapt. Early on in class, we went over some strategies very quickly that can be used or serve as a good base. Some of these consisted of black box and white box testing, dynamic and static testing, and some others. Each has their own way of testing, some can be better than others. Ultimately, it’s up to you to determine and figure out which one best suits you, the way you want to do things, and your code.

In this blog post, Janki Mehta writes about testing strategies, its key components, approaches, and some specific ones. They describe testing strategies as plans of “how software testing will be approached, executed, and managed throughout the software development life cycle.” They then describe the key components of the strategies, which are scope and overview, testing methodology, test environment specification, release control, risk analysis, testing tools, and review and approval. They dive into detail with the two approaches, proactive, where it focuses on detecting and catching bugs and defects before they even occur, and reactive, where it focuses on catching them afterwards. Some strategies they list were black box and white box testing, but some others too, like integration testing and regression testing, also describing what each of them are. At the end of the article, there are some final tips that can help easing the testing process and creating a comfortable environment when it comes to testing.

Knowing good strategies is important for testing code, and knowing multiple ones is even more important. It allows you to look around and figure out which fits best for your code and software, and adapt to it. Testing code can and probably will be difficult to get right all the time, learning all you can and having additional resources will be beneficial. I think that Mehta wrote a good article, it covers a lot of material, some of it can be seen as extra but it doesn’t hurt to know extra information, even if you can’t use it now. It’s clear the article is meant for a team to use as reference, but anyone can use it, not just a team. 

From the blog CS@Worcester – Cao's Thoughts by antcao and used with permission of the author. All other rights reserved by the author.

Postman Setup: TestProject

After exploring more of testing, and different strategies, I wondered about how testing could be automated. I came across a blog for Postman, on the TestProject website explaining Postman’s use in automated API testing. This blog is focused on providing a tutorial to understand how to use Postman to automate testing, rather than understanding various testing practices as seen in my previous blogs. The article’s title is Getting Started with using Postman for API Testing by Dave Westerveld

The blog first defines what an API is, as Postman is specifically for API testing. The blog defines API as Application Programming Interfaces. These APIs are extremely important in facilitating communication between software systems. Testing them is paramount for this reason, to assure they are working properly. This is where Postman comes in. It is an automated API tester, with a fully fledged application download. The article outlines the setup of Postman, and explains how to get it to cooperate with your system: First open the app of Postman that you’ve downloaded and then sign in. After this you are allowed to make API requests, the new button is then used and an API request is created. You name the request, and create a collection, where the requests are stored. Following setup, the article explains how to execute a Postman request. During setup, the article created the collection name JsonPlaceHolder, and then used that collection as the URL for the Request URL. After this, Postman will send the request for you. This can be used to compare results from different requests of an API and assure they are the same, although some manual input IS required in automated testing. However more intricate API Testing is shown in further tutorials with Postman.

This is a topic that interested me greatly, as I have been given many suggestions to look into API testing. Through the CS-443 course, I had been looking for more options to test and explore coding. Automated testing is something immensely interesting, and I appreciate the comprehensive guide provided by TestProject for Postman. This is of great value to me as I will continue to look through this guide and potentially post more blogs on this topic, as I explore automated testing. This first blog is mainly involving setup, and the basic concept of requests, but I look forward to further automated API testing using Postman, as these articles are very well structured.

Source:
https://blog.testproject.io/2020/07/15/getting-started-with-using-postman-for-api-testing/

From the blog CS@Worcester – WSU CS Blog: Ben Gelineau by Ben Gelineau and used with permission of the author. All other rights reserved by the author.