Category Archives: CS-443

Week 11

Deciding on a topic this week I decided to delve into Test Driven Development (TDD). I found an article with an engaging title “Test-Driven Development (TDD): A Time-Tested Recipe for Quality Software” by Ferdinando Santacroce. This would be very useful for me and the whole class because it’s fresh in our minds and we will continue to work with this concept. Getting a firmer grasp on this topic will help me with future assignments and homework. It’s always great to get an insider view with experience inside the field connecting it to what we learn in class.

This article begins with the history of TDD giving credit to Kent Beck one of the first “extreme programmers”. At the time nobody had ever reversed the idea of testing starting with a test instead of the actual code. The purpose of writing a test before the code would help programmers put them in the perspective of the maker making it easier to create the software. This would make more tunnel-focused code with much more simplicity because of just focusing on the test. Plus the codes get rapid feedback because all the tests have been made. TDD has the fastest feedback loop only surpassed by pair programing. Currently, TDD is widespread inside the field and several teams utilize it day to day. It’s hard to adapt to this type of coding scheme but with time it is proven to be a key to success. Minor grievances may also come up because this type of process can be too rigid or the lack of tools.  

After reading this article getting a glimpse into the history of how this came to be. It didn’t specifically specify when it started but I assume it was around the 90s because it mentions how common it is now. Understanding the benefits of doing this test answers my question why would you decide to do your coding process in reverse? What we have been learning is that it will be conventional to have code and then write the test connected to the already processed code. The benefits of cutting down time because of the faster feedback times and leading to less complicated code, I now understand its purpose. That is a recurring theme with code the simpler the better because you are never working alone. Maybe it is a self-contained project but your future self may not understand your complex code and updates to the code should be easy to do not a headache. 

https://semaphoreci.com/blog/test-driven-development

From the blog cs-wsu – DCO by dcastillo360 and used with permission of the author. All other rights reserved by the author.

Test Driven Development

Test driven development is an important method of developing which is based on first writing a test for what you want your program to do, this test will fail as you do not have any code written in orde for the test to pass but you then write the code which is necessary for the test to pass and then you continue repeating this process of writing a test then writing the code for said test to pass. You are encouraged to write the simplest possible code in order to make your test pass before moving on to the next test but you may need to do some refactoring between tests in order to ensure you do not have unused code, confusing methods or variables, etc. Test driven development is very helpful when it comes to testing the specifications of a system as you can write simple unit tests which would pass if a specification was met and when it fails you know that you still must add or change your code in order to make sure the specification was met for the end product. Other types of testing are also important to perform but test driven development can help you steer away from over complicated code and make sure that you do not have recurring duplication present when you regularly refactor between cycles.

I found this article to be particularly helpful when researching test driven development as it clearly breaks down the steps of test driven development in order for the reader to fully understand the process you must go through in order to follow this development method. Along with the thoroughly explained process this article also compares and shows how both acceptance test driven development and developer test driven development work together. As we just started working with test driven development in class I found this article to provide valuable insight into the definition and process of this testing/development model as it is something rather different compared to what we have worked on previously regarding testing as we usually have worked with code that needed tests written and not with tests that needed code to be written. Being new to TDD made it seem very confusing at first as it did not feel right to be writing the tests for code which did not even exist yet but the benefits of TDD are much easier to understand once you put this method into practice.

From the blog CS@Worcester – Dylan Brown Computer Science by dylanbrowncs and used with permission of the author. All other rights reserved by the author.

Test-Driven Development

For this week’s blog, I decided to find a blog that discusses test-driven development (TDD). I found a blog called “Test Driven Development is the best thing that has happened to software design” by Arek Torczuk. In this blog, the author walks through how they apply key elements through real examples. Throughout the blog, they explain their reasons for implementing TDD and walk through how to use TDD on code that is impossible to test. They split their explanation of how to test impossible code into small sections that include bits of example code to aid in the explanation. I found the organization of the blog along with the various examples to be particularly helpful in aiding the reader understand the topic and stay engaged.

The author first explains that TDD is implemented in a fail, pass, refactor cycle approach. They shorten the idea by explaining that “our focus remains on the ‘what’, and our knowledge of ‘how’ is postponed.” In this section, the author also provides a visual which I find to be effective in blatantly pointing out the important details of this section. They then go on to explain the differences between when tests are driven by code and when code is driven by tests. When tests are driven by code although the tests written for the code may pass it may not be the right approach as feedback about implementation and design may be lacking. There are 2 questions that one has to ask themselves when they take this approach: “When should I stop adding new tests?” And “Am I sure the implementation is finished?”. The latter approach (when code is driven by tests) forces you to ask yourself “What do I expect from the code?”. When code is driven by tests, you know when to stop. TDD provides fast feedback.

The various examples of code that are impossible to test were interesting to read through. One example I found fascinating was the “Bloated setup” and the “Mocking Hell” scenarios. The first scenario is where an object either has too many dependencies or the Single Responsibility principle has been broken. The author explained that in this case you should you should rethink your design. The latter is where a mock returns a mock that returns a mock.

Overall, I think this was an interesting read. I think reading through the various examples of how to test impossible code will be useful for the future as I will have to think through how to test different kinds of code and when I should rethink certain designs.

From the blog CS@Worcester – Live Laugh Code by Shamarah Ramirez and used with permission of the author. All other rights reserved by the author.

Week 11 Blog

This week’s blog will cover the main purpose of Object Oriented Testing and its usefulness. You most likely have heard the term “Object Oriented Programming”, which refers to a style of programming that utilizes classes, abstract classes, inheritance, polymorphism, concurrency, and more as a way of organizing code. These tools can be useful when dealing with multiple lines of code because it can be broken down into multiple files creating a more organized and readable product. Having a file with thousands of lines of code is a developers nightmare. Object Oriented Testing aims to test these systems and ensure they are behaving as expected. It is possible to have too much inheritance in a program, making it difficult to find where a piece of code is located, slowing down development. Unlike other test methods that primarily test function behavior, Object Oriented Testing analyzes the behavior of the entire class and its interactions with other files.

There are multiple techniques to Object Oriented Testing: Unit Testing, Integration Testing, Inheritance Testing, Polymorphism Testing, and Encapsulation Testing just to name a few. Unit testing refers to testing of individual components of the class before testing the interactions it has with other classes. Initially testing the classes functions will prevent scenarios where you can’t locate the bug in the program because there are too many inherited classes. An example is testing each function and ensuring the behavior. Integration testing refers to testing objects of different classes and ensuring they behave properly with all the components. Inheritance testing aims to test the relationship between parent and child classes. This technique of testing also tests overridden functions are properly implemented and are actually overriding the function. Polymorphism testing aims to verify that objects of different types can be used interchangeably. This type of testing ensures the behavior across all types of objects. Encapsulation testing tests access control and ensures the data being accessed is allowed to be accessed by the user.

The main benefits of running these tests is to detect defects early on rather than later in the development process. For this reason, it’s recommended to run tests throughout development. Object Oriented Testing ensures our project is modular, making it easier to maintain. In addition, it becomes easier to implement new features and classes without impacting existing code. Due to the never-ending demands of modern applications and the ever-evolving tech industry, the scalability of a program is crucial.

Blogs chosen: https://medium.com/@hamzakhan522001/object-oriented-testing-1f9619da40d0
and https://www.h2kinfosys.com/blog/object-oriented-testing/

From the blog CS@Worcester – Computer Science Through a Junior by Winston Luu and used with permission of the author. All other rights reserved by the author.

Test-Driven Development: Because Debugging is Overrated.

You know that heartbeat you skip when you press ‘run’ and pray everything works? Well, today I shall exhibit a certain method that has been around for some time that will have you save those skipped heartbeats for when your favorite TV show character nearly dies. Enter Test-Driven Development (TDD) – it’s kind of like having a buddy checking your work as you go, making sure you’re on track

Imagine you start cooking a new recipe you found. Would you start cooking without checking if you’ve got all the ingredients? You write a small test for a feature you’re about to whip up, see it fail (because it doesn’t exist yet), and then write just enough code to pass the test. It’s a cycle: write a test, code a bit, make it pass, and clean up your code without changing how it works. Rinse and repeat.

Yes, I’m not a telepath but I know what you are thinking right now, why even bother?

One benefit of TDD is that it nearly eradicates most of the bugs in your code, making you less likely to spend hours hunting down bugs. You’re checking your steps as you go, so you know exactly where things might have gone sideways.
Your code design is going to be more professional because when you write your tests first you can make your code more modular and easier to read, kind of like organizing your closet so that you can find your favorite shirt even in the dark.
Once you have a couple of tests, guess what? You can go update or refactor your code however you like, your tests will let you know if you broke something.
Apparently, the word online is that after getting used to it you’re actually going to code faster. The backtracking time to fix bugs adds a lot to your programming timer even if it doesn’t feel like it.

Okay, It’s not all Sunshine and Rainbows. I personally feel like Test-Driven Development feels like a drag at most times, especially for people who are not used to writing tests before you code, and from what I have experienced so far, writing good tests is an art form on its own. Still, once you start, you might just want to stick with it. The payoff in reducing headaches (I promise I’ll stop using this word in the future) and quality code will be worth it.

I really want to think of TDD as my coding companion, helping to keep my code clean and bug-free. It is somewhat of a mindset shift, more frontloaded work for sure but I feel like it will result in fewer late-night coding sessions and better-quality projects. Whether you are a solo developer or a team player, giving TDD a shot could be a game-changer. So try leading the way with tests next time you sit down to code and see how that goes.

Till next time,

Ano out.

References

https://testdriven.io/test-driven-development

https://www.browserstack.com/guide/what-is-test-driven-development

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.

Enhancing Code Quality: A Dive into Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis in JUnit

In the world of software development, ensuring code quality is paramount. It’s not just about writing code that works; it’s about ensuring that the code is robust, reliable, and maintainable. This is where various testing methodologies and tools come into play. In this blog post, we’ll explore three crucial aspects of code quality enhancement in JUnit: Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis.

Smoke and Acceptance Testing: Smoke testing, also known as build verification testing, is a preliminary test that focuses on ensuring that the most critical functionalities of an application work. It aims to identify fundamental issues that might hinder further testing. Acceptance testing, on the other hand, evaluates whether the software meets the acceptance criteria and is ready for release.

JUnit, a popular testing framework for Java, offers robust support for both smoke and acceptance testing. Through annotations and assertion methods, developers can easily write tests that verify the functionality of their code. By running these tests regularly, developers can catch regressions early in the development cycle, thereby ensuring a smoother development process and a higher quality end product.

For further information on Smoke and Acceptance Testing, you can refer to the documentation here.

Exploratory Testing: Exploratory testing is a hands-on approach where testers explore the software application without predefined test cases. Instead, testers rely on their domain knowledge, intuition, and creativity to uncover bugs and issues. While automated tests are valuable, exploratory testing can uncover issues that automated tests might miss.

In JUnit, exploratory testing can be facilitated through the use of parameterized tests and dynamic test generation. These features allow testers to generate test cases dynamically based on various inputs, enabling thorough exploration of the codebase.

To learn more about Exploratory Testing, you can explore the documentation here.

Static Analysis: Static analysis involves analyzing the code without executing it, typically to find potential defects or code smells. In JUnit, static analysis can be performed using various plugins and integrations with static analysis tools like FindBugs, PMD, and Checkstyle. These tools analyze the codebase for issues such as potential bugs, code style violations, and performance bottlenecks, providing developers with valuable insights into improving code quality.

For detailed information on Static Analysis in JUnit, you can refer to the respective documentation of static analysis tools and plugins integrated with JUnit.

In conclusion, leveraging Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis in JUnit can significantly enhance code quality, leading to more robust and reliable software applications. By incorporating these practices into the development workflow, teams can streamline the testing process and deliver higher quality code with confidence.

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

Chapter 4 of “Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman” focuses on the concept of “Confront Your Ignorance.”

This chapter highlights that acknowledging your limitations is key to growth. It offers a roadmap for identifying these gaps and strategies for filling them.

The chapter lays the foundation with the Dreyfus Model, a roadmap for skill development. It breaks down learning into five stages: Novice, Advanced Beginner, Competent, Proficient, and Expert. The authors emphasize understanding your current level and adopting a lifelong learning mentality.

Imagine your skills and experiences as a developer stacked together, like a toolbox. This toolbox is your “knowledge portfolio.” The chapter argues that for a successful, long-lasting career, you shouldn’t just have a hammer. Instead, aim to be a “generalizing specialist.” This means having a go-to tool (deep expertise) but also filling your toolbox with various other useful tools (proficiency in diverse areas). This versatility allows you to tackle more problems and adapt to changing needs in the software-development world.

The chapter outlines several strategies for effectively addressing your ignorance:

  1. Build a Solid Foundation: Focus on mastering the fundamentals of your field. A solid foundation will prepare you for more advanced learning and future growth.
  2. Learn How You Fail: Reflect on past experiences, both successes and failures, to identify areas where you can improve your knowledge. Use these insights to guide your future learning.
  3. Expose Your Ignorance: Accept that you’re still learning and don’t be afraid to admit you don’t have all the answers. See your knowledge gaps as steppingstones to becoming a master.
  4. Confront Your Ignorance: Don’t shy away from opportunities to learn. Ask questions, take classes, and constantly seek out new information to fill in the gaps in your understanding.
  5. Find Mentors: Seek out experienced individuals who can mentor you and share their knowledge. A good mentor can offer valuable advice and insights based on their own experiences.

The interesting and useful concerns about this chapter is it discusses the importance of recognizing and accepting that you don’t know everything. It encourages embracing your ignorance as a steppingstone to learning and growth.

This chapter has changed the way i think about my profession as it emphasizes the importance of continually learning and expanding your skills beyond just coding. It suggests that software development is not just about writing code but also about understanding the business domain, interacting with customers, and collaborating effectively with others.

In essence, Chapter 4 of “Apprenticeship Patterns” emphasizes the significance of admitting what you don’t know as a software developer. By recognizing your boundaries and actively pursuing chances to learn and improve, you can strengthen your abilities and progress in your software development career.

From the blog CS@Worcester – THE SOLID by isaacstephencs and used with permission of the author. All other rights reserved by the author.

Test Driven Development

When you go to write code, maybe you already know what you want the code to do, knowing what it should give you as outputs and answers, but you might not know how to go about writing the code itself. In test driven development, you start with writing the tests first, and then trying to pass those tests, slowly as you go. It sounds like a strange approach to it but it is not as bad as it sounds.

In this blog post, Arek Torczuk talks about test driven development, and how it is the best thing that can happen to software development. First, they start off by describing test driven development, where they say it is, simply, a failing phase, a passing phase, and then a refactoring phase. In the failing phase, we create a test that will fail. In the passing phase, we create or write code, minimal code, that will pass the test. In the refactoring phase, we clean up the tests. Typically with coding, you would write the code, and then write tests. However, Torczuk presents some problems with this way of code development, like when to stop writing tests, or when you are sure implementation is finished. With test driven development, they say there are benefits, such as when writing tests, it makes you ask yourself, what do you want the code to do. They say that you should know the answers to these tests before the code is written. They then go on to provide situations where code may be impossible to test, and how test driven development can be used to help that, like using mocking. They provide code examples with these too, to further help visualize solutions. They provide some additional sources at the end of the article in the event you would like to learn more about test driven development. 

This is a strange way to write code, and for those used to writing code before everything else, this can be a difficult adjustment. Personally, I found it fairly difficult to start, but afterwards I was able to write the tests, and then write the code to pass those tests, and then keep doing that. The tests do provide a build up of the code, instead of doing everything all at once, which was what Torczuk was trying to get at with his blog post. It allows the tests to provide the framework of the code and lay it out. 

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

Testing With Stubs

Recently in my Cs-443 class, Software Quality Assurance and Testing, we have been talking about unit testing using stubs. Honestly, I didn’t understand what stubs were during the classes themselves, but a blog called Why Stubs in Unit Testing Improve Integration Testing helped me understand what a stub is, as well as where and when it is used. In this blog written by Miroslaw Zielinski, he states ” Unit testing is more about isolating the function, method, or procedure, otherwise referred to as a unit. This isolation is done by stubbing out dependencies and forcing specific paths of execution. Stubs take the place of the code in the unit that is dependent on code outside the unit.” Stubs allow the person testing the code to test specific paths of execution within the code, allowing them to view different things such as if different parts of the code work and are reliable. I think that Zielinski gives a great example of why these stubs are used in his article. He states, “Once the stub is added, it will be consistently applied to the tested code. A user working on the “allocation failure” test case will have an easy way to install a special callback function into the stub, which will simulate the desired effect: allocation failure or do nothing since by default the stub returns a null pointer, which is expected for the test case.” This helped me understand why stubs are used, and the rest of the article helped me understand when they are used.

After reading more of the article, Zielinski began to explain why stubs are used. Although his explanation confused me a bit, I believe I got the jist of what he was trying to say. I believe that they are being used when you are trying to test lower-level modules while the upper-level modules have not been developed yet. Therefore you can use a stub, which acts like an upper-level module, in order to see how it will be treated. Zielinski also gives examples of when stubs aren’t good to use and what the limitations are “In instances where there’s not an original definition available for a stubbed function, what happens? How does the stub behave without a callback that defines the alternative behavior? The beauty of C/C++test is that it automatically detects this kind of situation. The stub will reconfigure itself during the test harness build time. It won’t call the original definition when no callback is installed and will return a safe default value.” I’m not really sure what he means by this, but I hope to learn more in the future.

Link: https://www.parasoft.com/blog/using-stubs-in-integration-level-testing/#:~:text=Unit%20testing%20is%20more%20about,on%20code%20outside%20the%20unit.

From the blog CS@Worcester – One pixel at a time by gizmo10203 and used with permission of the author. All other rights reserved by the author.

System Testing

System testing is a process of verifying the end behavior of a software application. System testing finds any errors, spaces, and missing requirements that could affect the software’s functionality. This is usually done after all the tests are completed, it’s important to test the software before releasing it to users. System testing main goals are to reduce risks, prevent defects, verify the design, and validate the system. System testing is an important step in ensuring the software is of great quality before it goes live. Addressing and identifying the errors or issues before making the software live can reduce any risks and make sure that it works perfectly for the users. Verifying the functionality of the completed system will help determine if it meets the requirements specified for that system. This is the best way to prevent any defects, errors, and missing requirements. System testing is also used to check if the system has been designed correctly and follows all the specifications. The process of verifying the accuracy and completeness of the system is the main objective of system testing. It’s to provide confidence that the system meets all of its requirements and will run as expected.

There are different types of system testing to look out for and plan for such as setting up the environment for the test case, creating a test case, creating test data, and running the test case. It’s important to make sure that the environment is set up so that you can write test cases by making sure that it has the right tools and frameworks that will be needed. When creating the test cases it’s important to make sure that the test case has all the necessary details about what the test case is testing for as well as how it will test it. The test data is created in thought of the inputs and outputs for the test case. While creating the test data it’s important to cover all of the critical fields and that nothing is left out. When running the test cases you want to make sure that it puts out the correct output, it should show if it passed or failed. I chose this topic because system testing is important to make sure that our system meets the requirements and runs without any problems. We started working on test cases recently so I thought getting more information on system testing would benefit our skills and any questions that anyone might have.

https://blog.qasource.com/what-is-system-testing-an-ultimate-beginners-guide

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