Software QA Log #3: Introducing Boundary Value Testing

During my introductory programming classes, I tended to think that simply running my code and using random values as input to see if any errors popped up was more than enough to ensure that my code was (at least at the time) sound. Perhaps, in ideal circumstances this could be an ideal testing method. After all, if I had an inkling of an idea of what is considered a valid or invalid input, I could simply use some somewhat random input values, see what happens, and call it a day. It works, right?

As tempting as this may be, I am still working on understanding how functional software testing works, what techniques exist and can be used, and how to implement the tools that are created specifically for functional testing. In fact, I did talk about JUnit testing in a previous post, which can automate the process of testing for valid and invalid inputs that we provide to the software. If we were to just use random values without having a specific pattern in mind while testing software, what conclusions we would end up with by the end of testing would not mean much in the long run.

One efficient technique of testing for valid and invalid inputs is Boundary Value Testing or Boundary Value Analysis (two terms that I may be using interchangeably), a software testing technique for which test cases are being written based on what the programs define an acceptable range of inputs to be. To be more specific, when using boundary value testing, a tester may use the values at the boundaries of a range as inputs. In essence, we use the range or set of acceptable values for any variables in the code as the test cases, rather than simply coming up with random valid or invalid values at our own discretion. Moreover, to conduct boundary value testing we take values near and at the boundaries of a defined range [min, max], with some such values being:
1) max and min: the values at the extremes of a range
2) max-: the value just below the upper limit of a range
3) min+: the value just above the lower limit of a range
Boundary value analysis can include more values near the extremes of a range based on the needs of specific test cases, thus increasing the testing complexity, though the above mentioned are actually very common among all variations of boundary value testing, which may even include values that fall outside of the valid range. The above values fall within the acceptable (or valid) range of values, thus if they are provided as inputs during testing, we can expect to get reasonable outputs and behaviors from the software in return.

Here is an example of boundary value analysis using mathematical sets:
Suppose we have the variable x of type int that has acceptable values within the range [a,b]. This essentially means that we can define the valid range of x as {x: x ≥ a and x ≤ b}, meaning that any value within and including a and b will result in the program behaving in a reasonable manner. Any value that fits the invalid range of {x: x < a and x > b}, on the other hand, may result in the program throwing exceptions.

A simple example of boundary value testing being used in JAVA is the following:

Source: Boundary-value analysis (Wikipedia)

Though boundary value analysis may not absolutely prevent errors and bugs from occurring while testing software, it is an extremely good point of reference that a tester can use when they are testing code. If one expects the software to behave in certain ways depending on specific value intervals, it can be fairly easy for the tester to adjust their approach around such specific intervals and have a better understanding of the software they are testing and how it should work.

Articles/Websites I read that discuss the topic of this post in greater detail:
1) https://celestialsys.com/blog/software-testing-boundary-value-analysis-equivalence-partitioning/
2) https://www.eviltester.com/2019/01/what-is-boundary-value-analysis.html
3) https://qualitance.com/blog/boundary-value-analysis-and-equivalence-partitioning/
4) https://blog.qatestlab.com/2016/02/19/boundary-value-testing/

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

JUnit 5 and Gradle

In this second assignment for the software quality Assur & test we had to practice writing more Junit5 test cases. We had given three java classes, product, customer, and order. Our job was to write Junit5 test classes. Different from the week before this time we had more test cases to write. I liked and disliked this assignment because I enjoyed writing the test cases but the part that was not my favorite was running gradle in the project. It gave me a lot of trouble until I figure out what was wrong with it.

I believe that like me, many students or developers like to write Junit5 test cases. In our assignments we just scratch the surface of the features offered by JUnit 5. To find out more, go to the JUnit 5 documentation, it covers a huge host of topics, including the features we’ve have used until now and many more in detail. What I personally like about writing in Junit is that it follows a modular approach, which makes extending the API easier. It provides a separation of concern, where writing tests and discovering/running them is served from different APIs. In essence, three main modules exist within JUnit 5: JUnit Platform + JUnit Jupiter + JUnit Vintage.

Another obstacle that I had for this assignment was running gradle in program. Gradle is an open-source build automation tool that is designed to be flexible enough to build almost any type of software. What I like about it is that gradle avoids unnecessary work by only running the tasks that need to run because their inputs or outputs have changed. When I run gradle in my computer some of the test cases failed even though they passed in my environment. The main problem was in one test case. My solution to this problem is think another way you can write your test case, and that’s what I did. I changed the test cases and added some import statement that were missing and no issue after that.

Overall, I enjoyed this assignment. I like writing Junit5, but I don’t enjoy gradle. I had used it before and always causing trouble for me. Hope in the future that things will run smoothly.

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

Software Quality Assurance and Testing Blog Post #2 (JUnit 5 Testing With Gradle)

The second assignment I worked on in my Software Quality Assurance and Testing class combined what we learned about JUnit 5 testing and using Gradle to automatically run all the tests fast and easy. This assignment proved to be more difficult than I was expecting, but in the end, I got very good at it and learned what I needed to. Downloading Gradle in the first place was my initial issue, since it seemed much easier to get it with a Windows machine than my Mac. Some classmates were kind enough to assist me and let me know about a software called Homebrew that basically is able to download Gradle for me. This was so helpful, and it was installed in no time! The second thing that make this assignment more difficult was that the actual tests I had to write were much harder than my first assignment. It took a lot of debugging and testing over and over again to finally get all of the tests to pass correctly. For some reason, many of the errors I ran into were primarily because I have made silly mistakes like grammar or syntax faults. All the repeated testing and debugging made me so much better at writing the methods correctly. The last thing that I would like to reflect on from this assignment is something I should have covered in my previous blog post. It is that pushing my projects to GitLab has changed. Of course, it has not changed that much, but just slightly. Rather than using the command “git push origin master,” I now have to write “git push origin main.” This is not too big of a deal for me, but at first I did not understand what I was doing wrong because of my pushes not working. I believe all of these things together will be a big part of my first exam in this class, and because of that, I am happy I was able to briefly discuss them in this blog to get a little extra review on them before that date!

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.

Software QA Log #2: I have been learning JUnit5 Testing lately.

In my previous blog-post, I talked about the importance of testing any product in order to ensure that it meets certain qualities and specifications, as well as work as intended. Software is among such products, as software goes through extensive testing before it becomes available to a wider range of users. Software testing includes conducting functional and non-functional testing, with the first focusing on testing if software runs as intended (by producing expect outputs and whatnot) and the latter focusing on non-functional aspects of software like performance. Today, I want to focus specifically on functional testing, more specifically on unit testing.

Although I wish to spend the rest of this post talking specifically about unit testing related to the JAVA programming language, I want to mention that unit testing is not exclusive to one programming language. During my earlier academic years, I learned to write unit test cases on C++ using CxxTest, an experience that I was able to carry over to JUnit5 as I started learning it in 2021.

Unit testing is a method of software testing that focuses on individual units of code. When testing for code written in object-oriented languages, a unit can be a function, a class, or an interface. While a novice programmer would simply run the code and provide their own input in order to determine whether the software behaves as expected, a programmer that is more familiar with using unit testing can automate the testing process by creating test cases for the units of code they wish to test, which would provide better coverage and much more insight to the tester regarding the behavior of the code compared to the feedback that simply running and inputting values to the code would provide. Though this method of testing is called “unit” testing, that is not to say that each function has to be tested in isolation. On the contrary, unit testing can be a very useful tool that can help a coder understand how each function interacts in tandem with other functions, which can make it much easier to troubleshoot and implement fixes.

As I mentioned earlier in this post, I began learning how to write JUnit5 unit test cases sometime earlier this year. Fundamentally, writing JUnit5 test cases is exactly the same thing as writing any other class in JAVA: it involves library imports, class definitions, instance variable and method implementations. Not too dissimilar to what a newer programmer would do when learning JAVA.

Depending on the kind and the complexity of test cases they could be writing, one could utilize the same functionalities that are used in the source code. The only difference is that JUnit5 introduces more functionalities that are used to run test cases. Such functionality is is the Assertions library. This method does the very thing a tester would do if they chose to run the code directly for testing; it checks if the value of output provided after execution is equal to the value a tester would expect the program to produce. Because it is possible to utilize multiple assertions in multiple test cases or for even multiple expected outputs, which can help save a tremendous amount of time of testing.

Though there are multiple other functionalities (such as annotations and whatnot), JUnit5 testing essentially boils down to its assertions; after all, it is the assertions that will show whether a test case has passed successfully and produced expected outputs, or has failed and has shown what has potentially gone awry.

The below image contains an example of a JUnit5 class with a test case:

Source: JUnit5 User Guide

One potential disadvantage that JUnit5 testing might present to programmers without much experience, such as myself, is that the order multiple test cases are run is not sequential. Rather, it is up to the compiler to run the test cases in any order it wishes to, which can be somewhat frustrating when the success or failure of a test case depends upon the success or failure of a test case(s) that exist(s) before it. Luckily, JUnit5 does have a way to run test cases in a specific order depending on the needs of the programmer who is writing the test cases.

Overall, learning how to write test cases can be a blessing for a programmer. Though this might not be necessary on programs of a smaller scale, it is extremely important to ensure that more complex software is tested thoroughly enough so that it functions at the best of its capabilities. After all, this blog is involved with Quality Assurance and Testing, thus making unit testing a very vital concept to be well-versed in.

Articles/Websites I read that discuss the topic of this post in greater detail:
1) https://www.edureka.co/blog/junit-tutorial/
2) https://junit.org/junit5/docs/current/user-guide/
3) https://www.h2kinfosys.com/blog/junit-testing/
4) https://blog.testproject.io/2019/02/26/junit-5/
5) https://smartbear.com/learn/automated-testing/software-testing-methodologies/

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

Apprenticeship Patterns Blog Post #6

With the semester nearing its end, I do not have many more apprenticeship patterns to review on here. Because of this, I am trying to choose patterns that have the most relatability to me. For that reason, I chose to review the pattern in the book entitled Sustainable Motivations. It is all about developing your technical skills in order to maintain your ability to work well given different project goals and situations. The problem that I am trying to solve by learning this skill/pattern is the fact that this line of job is often rigorous, difficult, and stressful. I need to learn to love what I do and be good at what I do when I am not loving it. The book explains how there are many days, weeks, and months where my job will be extremely fun and enjoyable, but that there are also many times when it will be quite the opposite. The important thing is for me to keep moving and working through the not-so-good times and continue to stay motivated as much as I can throughout the process. The book has some great tips and examples of how to stay motivated during the harder times. First, I should be working hard to move up in the ladder of my jobs rather than just fulfilling my personal duties. This is especially apparent when I am not enjoying what I am working on and mainly working for the money aspect. The second example is when I could possibly want to quit and I decide to pull through and finish what I am working on. It proves valuable and exciting to finish things whether you liked the process or not. Lastly, the book shows that pulling through the tough and hard times will help your reputation as a worker and a programmer immensely and that in doing so, more opportunities with open up. This whole pattern resonates with me so much because of how ominous real life jobs feel to me at the moment. I know that if I follow those three examples/tips, I will not regret it! Bad times will happen, and pulling through will only help me grow.

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.

Retreat into Competence

            The learning pattern “Retreat into Competence” from the Apprenticeship Patterns book is something that gave me great comfort to read. The idea is that, when overwhelmed by your ignorance in the face of a complex problem or task, it can be beneficial to temporarily fall back onto what you know. This can boost your confidence, refresh your mind, and/or reveal relevant applications of the knowledge you do have. All of these things can make tackling your ignorance easier, or at least a little more manageable.

            As the book points out time and time again, it is very beneficial to accept what you don’t know and face it head on, but sometimes this can leave you stranded. There are many times that learning new concepts can feel like reading a different language or can make my eyes glaze over for 10 minutes before I realize that I haven’t been paying attention and need to start again. In times like these, I believe this learning pattern is very beneficial.

            For example, in the current course, I needed to learn Vue.js for the project. It’s a pretty straightforward task, but doing it was not very easy. I still wouldn’t call myself comfortable with Vue.js, but I definitely made some substantial progress in the face of feeling totally overwhelmed. When there were times that I didn’t know how to approach the sub-problems of learning that I faced, I found it supremely useful to take time off and look at other parts of the project which I felt more comfortable with. I retreated to things like looking over the backend API endpoints and practicing them a little bit before returning to Vue.js. These breaks allowed my mind to refresh as I could read over materials again with a better understanding and then practice the problems I was facing.

            I think the main difference in what I was doing was that I did not set blocks of time for my retreats into competence. When I returned to my real work, I sure felt more confident and had less of a sense of imposter syndrome, but sometimes these breaks were too long and help me back from real progress. I think measuring some finite time will help greatly in picking myself back up without being a hinderance to progress. There are plenty of times I know I will become lost in the capstone, as well as down the road in every project I work on, so I predict this learning pattern will be a very helpful tool.

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

Sprint 1 Retrospective

Summary

In this sprint, I mainly did the following things:

  • Learn Scrum – We all had to review how Scrum works and the different roles.
  • Understand GuestInfoBackend – I read through the Architecture to understand how the GuestInfoBackend is supposed to work.
  • Review Docker – I did research and found useful links to help us remember how to use Docker.
  • Docker Example – I created a basic docker example that we can go back to as a reference.
  • Learn Express – I did research into Node, Express, and OpenAPI for the backend.
  • Express Example – I created a basic express example with a few routes and such.

What Worked Well

I think overall, all of us in our team are all on the same page about this class. We understand what we have to do and no one is falling too far behind or going too far ahead. We’re good at helping each other when we need it and we try to put the team first.

Learning how cards work on the boards went really well I think. After that sprint, I think we all have a decent understanding of how to add labels, assign people, etc; moreover, we understand how to utilize the cards to aid workflow.

I also think we overall did a decent job of researching the materials we needed to and we have a decent understanding of the tools involved such as Docker, Vue, OpenAPI, etc.

What Didn’t Work Well

The biggest difficulty comes from the fact that this is a class rather than an actual job. That means we only have 3 hours of class time per week, and then we need to allocate personal time to work. I find this especially challenging when I have other homework to do, and other personal projects I want to work on such as creating a version of the C programming language that has python-like syntax. The biggest limiting factor to all of this is time, with the second one being motivation/interest. I find it incredibly easy to spend an entire day working on something I really enjoy and I find it incredibly hard to work for even half an hour on something I don’t care about. This falls somewhere in between the extremes.

Another thing that adds difficulty is, at times, it feels like we have no idea what we have to get done. The problem is that when that happens, we don’t even know where to start asking questions to figure out where to go.

What Changes Could be Made to Improve as a Team

Overall, we could probably work together more both in class and outside of class. Most of our work has been done mostly alone unless necessary, however there are some times when it would be convenient or useful to work with more people at once.

We all could do better at managing time, as previously mentioned. Using card due dates, we can help keep each other working in a decent time frame.

What Changes Could be Made to Improve as an Individual

I could be more vocal in classes, as well as work more outside of class. This applies to both working more on this class in my own time, as well as working on my other classes in my own time.

From the blog CS@Worcester – The Introspective Thinker by David MacDonald and used with permission of the author. All other rights reserved by the author.

CS448 Retrospective Blog #1

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/guestinfosystem/community/-/issues/8

Here I put links for tutorials and relevant articles for learning MongoDB.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/guestinfosystem/community/-/issues/27

This card shows I was allocated to the event system cross-cutting team.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/guestinfosystem/community/-/issues/16

This is a card I created for learning how to connect the backend to mongoDB.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/guestinfosystem/community/-/issues/18

This card is for an example mongoDB project.

Our first sprint was filled with learning, both about the tools we need and about the sprint process. I think there are many things that worked well. First, I think our team composition right now is good. We all know each other from previous classes, and we are comfortable with talking casually to each other. This is good because there was no initial awkward phase – we were able to get straight to working with each other. Another thing that worked well was asking important questions for each other on gitlab. While we did not use the cards to their fullest potential, having email notifications for gitlab really forced me to pay attention to the cards. My discord does not have notifications turned on, so I must actively check for new messages. On gitlab the email notifications made me extra aware of new comments on cards and any changes to the cards.

There were of course many things that did not go so well. Somethings I failed to realize is that gitlab should be the place where I keep all my work. I followed quite a few tutorials, so I have a few mongodb projects on my own computer. I should have been actively adding them to gitlab as well. My issue was that I did not feel like I had a finished product worth sharing. I should have realized that was okay and posted that anyway.  Another thing that did work so well was communicating mostly on discord. We did a lot of brainstorming and communicating in class through voice chat. Because we did not write down every single thing we spoke about, some things were forgotten or missed. We should definitely be trying to use text chat more, but most of our communication should probably be through gitlab to maintain a permanent record of what is being discussed.

As a team we should definitely work on mostly using gitlab cards for communication. As a team we should also try to contribute more evenly in discussions and with product owner meetings. I know I am not contributing enough and we should all be taking responsibility for our team instead of just letting one or two people do all the talking for us. Overall though I feel like my team is very solid and we work well together.

As an individual I should work firstly on time management. Having sprints like this is almost deceptive in a way. This isn’t the kind of thing you can do all the work right at the end of the sprint. It really isn’t possible to complete most of the cards like that. The work should be spread out, especially since it is cumulative. Some cards need to be completed so you know how to complete other cards. I also have to work on communicating with my group more. As the system is more fleshed out, we are going to have to work together more to combine the parts we have created. Right now we are sort of working independently and just checking in with each other. I will have to share the work I am doing with he rest of my team very frequently by pushing it to gitlab instead of just waiting to show them during class.

I went into this sprint very intimidated by the size of this project. After finishing it I feel a bit better because I know how sprints work now and we have a clearer vision of what we are going to do for this project. The next sprint will definitely be an improvement over our first.

From the blog CS@Worcester – Half-Cooked Coding by alexmle1999 and used with permission of the author. All other rights reserved by the author.

Share What You Learn -Apprenticeship Pattern

The “Share What You Learn” apprenticeship pattern, written by Adewale Oshineye and Dave Hoover in the book Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman, 2009, is about sharing your knowledge. This is for software apprentices who have solely focused on their own growth/improvement. Sharing what you learn can benefit yourself as well as others. This is because it helps you learn to communicate what you know effectively, but also helps people who are on the same path as you, trying to learn the same things.

Maintaining a blog, tutorial channel, etc. during your early apprenticeship years can be great for your growth as a developer. You may feel like you only have a basic understanding of some topics that you have just learned, but this may benefit others more than you would think. As the book states, your basic understanding will translate to an easy to understand, straight to the point article, blog post, etc. that will help other apprentices who are right behind you in the journey to becoming a master. So don’t think that you need to leave it to someone who has an extreme in depth understanding of the topic, often times what they will give back to the community will not be as beginner friendly. You must be careful when sharing knowledge though and make sure that you are not spilling a companies secrets that can ruin your relationship with your team or get you in legal trouble.

I like this apprenticeship pattern in particular because it benefits yourself and others at the same time. Teaching is a great way to learn for both the teacher him/herself, and the student/learner. A certain part of this pattern really caught my attention and that is to not worry about leaving these posts/tutorials to people who have greater knowledge of the topic. Often times when learning something new, I will go to forums rather than tutorials. On these forums you can often find threads where students are asking the same questions about a topic that you are wondering yourself, and a lot of times other students will respond to these questions with their understanding of the topic. This is a great starting point for learning something new because often times there are basic, easy to understand, straight to the point responses that can kickstart your learning of the topic.

Hoover, D. H., & Oshineye, A. (2010). Apprenticeship patterns: Guidance for the aspiring software craftsman. Sebastopol, CA: O’Reilly.

From the blog CS@Worcester – Austins CS Site by Austin Engel and used with permission of the author. All other rights reserved by the author.

Concrete Skills – Apprenticeship Patterns

The main focus of this apprenticeship pattern called concrete skills is to have a fundamental base. A person can’t just rely on having the ability to learn something, but they need to show that they already have some skills that they have learned and improved on over the years. Also, these skills directly relate to software constructing such as being familiar with a certain programming language and implementing different features that can be useful for a company. While it is important and recommended to have many soft skill qualities, you can’t solely rely on this to land a job relating to software. You need to be able to showcase technical skills and so this pattern talks about taking actions to improve skills that are needed for the certain job criteria. It recommends to look at cover letters of individuals who are currently doing the job you hope to seek and copy down discrete skills listed on it that you can use to improve yourself.

I think this pattern has a really great concept that software apprentices can use to improve their knowledge for programming and other aspects of engineering. We can’t just have the mindset that we can learn new things when the time is right and just try to learn it then. We need to do some more research on our own and try our best to not be relying on others to carry us to learn fundamentals. People in work and a team don’t want a team member who they constantly have to monitor and essentially babysit for them to complete their work. We need to learn the essentials for the required job and practice to implement those skills on our own to show a boss or team members that we are capable of doing the work. This will prove that you are in fact able to learn and down the line will be capable of learning a new software or process that is often the case with the technological advancement of the world at a rapid pace. Overall, I think once we follow this pattern in a practical sense and change our mindset, we will see vast changes in our skills as well as the way we look at learning.

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.