Category Archives: CS-443

Technical Review

When working on a big project, in a big team, with a lot of other people working together, things can become confusing. Sometimes, code may not work, or you will not entirely understand what is happening. The best thing to do is step back and take a technical review. Review the code, the goals, and any other areas that may be in need of improvement or assistance. Take the time to straighten things out so you and the team can get back to work efficiently and effectively. But how do you go about a technical review?

In this blog post, Tony Karrer talks about what a technical review is, some ways to identify when you need to review, some strategies, and some areas of review. They describe a technical review as “a deep-dive assessment of your software, infrastructure, team and processes,” and that “it provides findings and recommendations intended to foster a mutual understanding between business and software leaders, shedding light on the current state of your technology and your team.” Some signs that you are in need of a technical review are slow or late delivery, random or persistent bugs, and sleepless nights from strategic worries. However, taking a technical review shouldn’t just be in response to malfunction, it can be due to scaling and new markets, keeping up with competition, outgrowing your stack, changes to the tech team, or simply because you want to be on top of things. Karrer describes four strategies, each different from the other, ranging from general to specific and in depth. They are straightforward analysis, pragmatic assessment, expert recommendations, and finding sessions. After determining which strategy you are comfortable with, you can go ahead and start reviewing. They provide some examples of where you may want to review, including background information to get a general idea of the project, architecture, targeted code, or process and team. If there are areas that need work or are struggling, then that is one hundred percent a spot you want to review. While you are doing that, create a summary and list your findings, and include some recommendations or solutions if you have any. Finally, bring them to the review meeting, where you will review the project together with your team and sort out the issues and find possible solutions.

Doing this in class was actually fairly helpful. I feel like if it was my code, I would have found more benefit in it, but I understand the premise of it, it’s good to have multiple people look at the code and come together and see what kind of issues we found. 

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

Testable code

In my last post, I highlighted a blog that gives an overview of unit testing and how we can use it to increase the quality and efficiency of our testing or debugging processes. The point of unit testing is to test “units” or isolated methods, classes, or modules of our code to determine if there are any issues. Writing code with unit testing in mind makes it simpler for developers to debug their code. I felt this next blog, “TDD: Writing Testable Code,” by Eric Elliott, would help further readers’ understanding of writing this kind of code and the benefits that come from it.

Elliott’s blog discusses many aspects of writing testable code, including tight coupling, test-driven development, separation of concerns, and an overview of different data management strategies. He describes how tight coupling limits testability and provides strategies to reduce it, including TDD. He also discusses the benefits of testing first vs. testing after, with test-first being the main focus of test-driven development. He goes on to describe data management strategies.

Reading this post brought my attention to an important aspect of software development, which is influencing a specific type of developer culture that improves the quality of our software as a whole. Writing with testability in mind makes it easier for the users, increases the adaptability of our code, and allows us to fix issues without revamping the whole system. 

The breakdown of tight coupling and the different forms they can take was comprehensive, giving me a straightforward explanation of what I should consider when writing code. Elliott gave 11 forms and causes of tight coupling, including parent class dependencies, temporal coupling, and event chains. TDD was something I was already aware of, but the benefits of using and detriments of not using TDD were still insightful for how we should be taking our development step by step, failure by failure until we have testable code. The separations of concerns were interesting. He says we should isolate our code by concerns, including business and state logic, user interface, and I/O & effects. Separating these into separate modules allows us to test and understand each independently. 

I plan to consider all of these strategies when developing projects in the future. I will use test-driven development to limit the tight coupling of my modules, classes, methods, etc., to ensure that my code is readable and testable and that each of its concerns are independent from each other. 

From the blog CS@Worcester – KindlCoding by jkindl and used with permission of the author. All other rights reserved by the author.

Blog #4: First Exposure to Testing

Before being exposed to JUnit, my only experience with automated testing was through CxxTest while I was learning C++. Once I started to learn JUnit both the syntax and general format seemed to ring a bell. This caused me to check back at my previous C++ programs to find that the assertion-based testing was identical to that of JUnit. After seeing these two side by side I was curious about the comparisons between these two testing frameworks and whether CxxTest had any advantages over that of JUnit.

While looking for an article discussing the full capabilities of CxxTest, I stumbled upon a blog, Exploring the C++ Unit Testing Jungle by user @noel_llopis, which seemed to provided extensive explanations of each popular testing framework for C++ at the time. Do note that this post was written in 2010, so popular testing frameworks from then may have faded into obscurity and new frameworks may be used in their place. My main allure to this article was Llopis’s section describing his experience with CxxTest and how testing frameworks required a little more work from the user back in 2010. Llopis praised CxxTest for it’s relative simplicity in how it’s imported into a program and how it requires much less dependencies. From his explanation, I’ve learned that testing frameworks used to require certain formatting within the file and potentially other libraries for the tests to function. CxxTest, similar to JUnit, can operate by itself with much less dependencies than it’s competitors (at the time). A feature that JUnit lacks that CxxTest contains is the ability to natively mock objects. JUnit does have this ability, but requires the user to add another resource to JUnit meanwhile, CxxTest has this functionality immediately. One downside that the author does mention is that CxxTest did require “use of a scripting language as part of the build process”(Llopis), this may create a barrier of entry to less experienced developers.

While comparing these two testing frameworks, I found myself asking a new question of ‘how accessible or inaccessible were testing frameworks of the past’. Llopis seemed to be enthusiastic about features that I held to be common for all frameworks to have. Additionally writing about this did make me wish that I spent more time in the past programming with C++ outside of classes. Reading this did help expand my knowledge of how CxxTest operates, so when I do inevitably go back to refine my C++ skills I’ll be ready to pickup this framework once more. Between JUnit and CxxTest, there are many surface layer similarities, as both are unit testing frameworks. The differences seem to lie in smaller features that some developers may depend on, such as mocking. After having experience in both I find it hard to chose one or the other as they both generally function the same and have similar levels of accessibility.

-AG

Source: https://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle

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

Blog #3: Testing Beyond JUnit

Throughout my experience with Software Quality Assurance, I’ve used two different types of testing frameworks. The most recent is JUnit as I’ve just learned how to use it earlier this year, and the other being CxxTest which I’ve forgotten most of (including its name) until writing this. Each of these operates for different languages, JUnit for Java, and CxxTest for C++. The differences between these two made me curious whether a framework worked for more than one language at once. Note, that frameworks such as CTest that work for both C and C++ I do not include as both exist within the C family. As I searched for a framework that answered my question I stumbled upon Selenium and subsequent articles comparing it to that of JUnit. These comparisons drew my attention and sent me down a path to understand what Selenium is.

Before getting into specifics I must introduce a few definitions that help differentiate these two frameworks. Unit testing is the method of testing smaller increments of source code to ensure that each ‘unit’ works as intended and meets the developers’ specifications. This lays the foundation for later development. End-to-end testing focuses on testing components where the user interacts with the program directly. This tests components such as UI and web applications. JUnit focuses on unit testing with code programmed in Java meanwhile, Selenium focuses on end-to-end testing with multiple different languages including Java. Fundamentally these frameworks are testing different aspects of software development, therefore any comparison between the two must be taken with a bit of nuance.

With definitions aside, we can now talk about what makes these frameworks unique. A community post on StackShare, JUnit Vs Selenium, gives a concise view into what make these frameworks differ. My experience with frameworks has only existed within IDEs however, Selenium is supported on browser and web driver tools. Additionally, Selenium tests run within a browser, meanwhile JUnits require a Java Virtual Machine to be created. One downside of Selenium is its requirements for dependencies, as opposed to JUnit which can be imported into your program. I’m more partial to JUnit as I only have experience with back-end development, so Selenium isn’t directed towards a developer such as myself. With that being said, those who are more experienced in front-end development may find the requirements for dependencies and browser configurations to be a small cost for its flexibility with testing.

I have a little experience with front-end development, so I can understand how the tools provided by Selenium could be invaluable. A lesson I’ve learned from this dive into Selenium is that all aspects of development (Ex: Front vs Back end) will require some form of automated testing. Additionally, testing that may be easy for one department may be more complex for another. With these different areas of testing also come different methods. End-to-end testing will be noticeably different than unit testing, as each method focuses on a specific function of the software.

-AG

Source: https://stackshare.io/stackups/junit-vs-selenium

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

Security Testing

Security testing is an important part of software testing, it makes sure to find any weaknesses in the software and if our data is protected from intruders. Security testing is important because it helps us ensure that our software has no weak spots and that our data and information are safe. There are so many versions of security testing like password cracking, penetration testing, and vulnerability. Those three topics are some of the main ideas of security testing and understanding the importance of keeping personal information safe. Password cracking testing is when the system identifies weak passwords and helps make sure that people use stronger passwords. Penetration testing is done by assessing the system by using different techniques, the purpose of it is to protect the important data of the users who don’t have access to the system. Vulnerability testing is used to identify the weakest attributes in the system that can be used by destructive software. A lot can cause the software to be vulnerable like a bug in the software, wrong software testing, and the presence of a bad code. 

I chose this topic because security testing is important in our software testing class and this blog has a lot of information on how it works. It’s important to know more about how our private data is saved from hackers and how safe our software is. I believe that this helped me learn more about security testing like how penetration testing uses different techniques like the black box and white box testing method to detect any vulnerabilities in our software. Security testing is to make sure that applications are not able to leak private information and can handle a threat like hackers. I already knew before reading how important it is for our information and making sure that our passwords are not easy for hackers to figure out but I thought penetration testing was interesting to learn about because I didn’t know it used so many different techniques to find any vulnerabilities. Security testing is about keeping our information safe as well as our software safe from any intruders and I believe that this blog gave the best explanation and information about it.

https://www.idexcel.com/blog/tag/security-testing/

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.

CS-443: Week 14

Behavior-Driven Development (BDD)

Behavior Driven development is an approach where the focus is set on the behavior of an application for the purposes of a business. This focus is to find a common ground between developers, quality assurance teams, and business professionals. Common ground is found by defining behaviors that are written in plain language, allowing everyone to understand and agree upon the software’s behavior.

BDD Process

Behavior driven development begins with defining behaviors in “feature files” which are used throughout the development process. Behaviors are straightforward statements that outline a specific process in a predetermined format.

Behaviors are written in a language called Gherkin, which use simple words such as “Given”, “When”, and “Then.” An example behavior would be, “Given the user enters an incorrect password, When they click the login button, Then they should be prompted with an error to reenter their password.” These behaviors are turned into tests with tools that check if the software behaves as intended. Because everyone is involved in this process, and agrees on the final product, confusion can be avoided.

Advantages to BDD

Behavior driven development leads to advantages that would otherwise be lost with other development approaches. A key advantage with BDD is better communication and collaboration. This is due to the nature of BDD as everyone from business, to quality assurance, to developers, meet together and plan everything. Because there is better communication, requirement understanding also increases. This is because requirements are explicitly defined, and everyone agrees what should be done. Due to the increase in requirement understanding, testers are made aware exactly what requirements should be tested. Ultimately the chances for the final product to be different than what was intended is less, saving time and effort.

Disadvantages to BDD

Because BDD is different from other development approaches, adopting the practice can be difficult. This is because teams are used to working amongst themselves, then meeting with the other teams once a final product, or an iteration of the final product has been completed. Waiting until a product has finished development before meeting the other teams can lead to wasted time and effort because what is actually delivered may be different than what the business team intended. Another reason why BDD can be hard to get used to is the overemphasis and learning curve with the tools necessary for BDD. Teams can get off track because they get caught up in learning Gherkin syntax and other tools.

Conclusion

This article was chosen because topics were easy to understand with the use of real world examples. Once past the learning curve, behavior driven development seems like a useful approach that fosters strong collaboration and communication. I was unaware of tools like Gherkin and Cucumber that are used to process the feature files, so learning about them was interesting. This approach is unlike others I have seen in the past; however, I am curious about how is all works. I will be looking into these tools in the future.

Resources:

https://www.browserstack.com/guide/what-is-bdd

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

Test Driven Development

The last few weeks of class have all been about Test Driven Development. Test Driven Development is when you use tests in order to guide you into developing software. According to a website called martinfowler, there are three main steps that we follow repeatedly. Those steps are:

  1. “Write a test for the next bit of functionality you want to add.
  2. Write the functional code until the test passes.
  3. Refactor both new and old code to make it well structured.”

Essentially what this means is you create a list of things that you want included in your test, then you create a test for just one of those items. Once you create the test, you implement the code in order to get the test to pass. Once it passes, then you move on to creating the next test and getting that test to pass. If it causes the previous test you fail, you refractor until all of the current tests pass, then you repeat until all of the items you need are done. I personally find writing the test first to be a lot easier than writing the code first. That way, while you’re creating the code, you have an example to look back at so you know exactly what you want it to do. On top of that, focusing on one part of the code at a time makes it a little easier to develop the code without making mistakes, as you aren’t focusing on the entire program at once, just one small part at a time. According to the article, this form of development has two main benefits. It says “Most obviously it’s a way to get SelfTestingCode, since we can only write some functional code in response to making a test pass. The second benefit is that thinking about the test first forces us to think about the interface to the code first. This focus on interface and how you use a class helps us separate interface from implementation, a key element of good design that many programmers struggle with.” I chose this article as my source because I thought it did it a really good job explaining what to do step by step so you don’t get confused. On top of that, it explains the benefits and consequences of this method and how to avoid/achieve them. This article helped me further understand Test Driven Development and why it is useful.

Source: https://martinfowler.com/bliki/TestDrivenDevelopment.html

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.

Common Mistakes in Software Testing

The blog post, “The 3 Biggest Software Testing Mistakes” from Daniel Knott focused on highlighting vital mistakes that software testing groups frequently come upon in their testing strategies. I chose this blog post because as we continue to learn different software testing strategies in class I think it was important to highlight some mistakes that could be made as a tester so we can avoid these in the future. 

 The first mistake that Knott highlighted was the mistake of not asking enough questions. When you are working as a tester your first job should be to ask as many questions during the development phase of the product as possible. This will allow you to verify that the product will work as intended for the customer. These questions should be highlighting product features, limitations, etc. The second mistake is trying to automate everything. Automation if done right can be very helpful however there are scenarios where automation can do more harm than good. Knott says that many teams mistakenly aim to automate everything, often driven by those unfamiliar with automation’s true benefits. Some parts of the code that are still in development, may not be ready for automation, while other areas will require detailed quality checks that automation cannot provide. Due to this, a risk assessment and informed questioning should precede test automation while working. Once suitable areas for automation are identified, decisions on the level of automated checks should be made by the team.The third mistake in software testing is reusing the same test data repeatedly. Software testing heavily relies on data such as text, images, or voice, and system configurations. Reusing test data compromises its integrity. The system’s state or configuration may change between tests which could affect results. To effectively test an application, the development team must define and generate appropriate test data. Generating test data can be complex, depending on the system’s intricacy and technologies involved. Ideally, scripts can create test data for specific tests, allowing for deletion or reset afterward. The conclusion of the blog post has Knott describing how mistakes can be good as they are a part of growing as a software tester. The best thing we can do is to be transparent about our mistakes to allow for a culture of learning.

After reading this blog post, I believe that I am now more confident and informed about how a software tester should go about testing strategies. Being able to identify common mistakes will be beneficial so I can avoid doing those mistakes in my own work. I found it interesting the fine line between automation since it can be both beneficial and harmful depending on just what you are working on. This is why as I read it is best to be left to a team decision as automation has its own list of pros and cons.

https://shiftsync.tricentis.com/testing-strategies-methodologies-42/the-3-biggest-software-testing-mistakes-95

From the blog CS@Worcester – Giovanni Casiano – Software Development by Giovanni Casiano and used with permission of the author. All other rights reserved by the author.

Object Oriented Testing

For this week’s blog post, I decided to discuss the article “Object-oriented Testing in Software Testing” by Mitali Varatiya. I chose this article because it compliments the object oriented testing topic in the syllabus. This article discusses what object oriented testing is, how you can develop test cases with object oriented testing, how to implement object oriented testing, different techniques with implementing object oriented testing, and challenges associated with the implementation of object oriented testing.

The author first discusses how object oriented testing can be done at multiple levels of a program, for example the algorithmic, class, cluster, and system levels. “Object Oriented testing can be performed at different levels to detect the issues. At the algorithmic level, a single module of every class should be tested. As discussed earlier, testing of classes is the main concern of the Object Oriented program. Every class gets tested as an individual entity at the class level. Generally, programmers who are creating the classes are involved in testing. Test cases for Object-Oriented Testing in Software Testing can be constructed based on the requirement specifications, programming language, and models.” The author then goes on to discuss how, at the class level, testing focuses on the integration of individual classes and their interactions with other classes in the program. “Once class-level testing is done, Cluster level testing will be performed. Cluster-level testing is the integration of individual classes. The main purpose of doing integration testing is to verify the interconnection between classes and how well they perform interclass interactions.” The author also discusses some ways in which object oriented test cases can be developed.

The author states that conventional methods of developing test cases are sufficient for creating object oriented test cases, but there are some features that may be helpful with object oriented testing that might be looked over when using more typical techniques on their own. “The following points should be considered while creating test cases for object-oriented environments. Which class is going to be tested should be mentioned properly within the test cases. What is the purpose of using particular test cases? What external pre-condition needs to be conducted while performing the test case? All the states should be specified for testing.” The author then discusses some of the challenges with implementing object oriented testing.

Some challenges that are associated with implementing object oriented testing as described by the author are the impossibility of dynamic testing, the necessity of different types of testing to be implemented to properly test the program, and the difficulties associated with the implementation of testing for inheritance in object oriented programs.

Article: https://www.scaler.com/topics/software-testing/object-oriented-testing-in-software-testing/

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.

Understanding Test-Driven Development (TDD)

In a recent episode of the Python Test Podcast, titled “TDD: Don’t Be Afraid of Test-Driven Development”, developer Chris May shared his journey with Test-Driven Development (TDD).  If you’re a programmer interested in improving your code quality and development process, this blog post offers a summary of the discussion and explores why TDD is a powerful technique.

What is Test-Driven Development?

TDD turns the traditional coding process on its head. Instead of writing a large chunk of code and hoping it works, you start by defining the precise behavior you expect from a piece of code. These expectations are written as tests, and they will initially fail because the code itself doesn’t exist yet.

Key Concepts and Benefits of TDD

The core of TDD is the “Red-Green-Refactor” cycle:

  1. Red: Write a failing test that reflects a desired feature or behavior.
  2. Green: Write the simplest possible code to make the test pass.
  3. Refactor: Improve the code’s design and readability while ensuring all tests continue to pass.

This approach offers several key benefits:

  • Improved Code Design: By focusing on functionality first, TDD encourages you to create well-structured, modular code.
  • Less Debugging: Catching errors as early as possible through tests greatly reduces time spent troubleshooting complex issues later on.
  • Increased Confidence: A comprehensive test suite provides a safety net, allowing you to make code changes with less fear of breaking existing functionality.
  • Living Documentation: Tests serve as a clear explanation of how your code is intended to work.

Overcoming Challenges with TDD

As Chris May discussed in the podcast, TDD requires a change in how you think about coding. Here are some common concerns and how to address them:

  • “It feels too slow”: It’s true that initially, TDD might seem to slow you down. However, the time saved from reduced debugging and a more solid codebase easily makes up for it in the long run.
  • “I don’t know how to write tests”: Learning to write effective tests is a skill in itself. Start simple and leverage online tutorials and resources specific to your programming language.

Resources for Learning TDD

  • Books:
    • “Test-Driven Development by Example” by Kent Beck
    • “Growing Object-Oriented Software, Guided by Tests” by Steve Freeman and Nat Pryce
  • Online Tutorials: Explore the numerous tutorials and guides tailored to different programming languages.

Conclusion

While it may have a learning curve, Test-Driven Development offers a structured and rewarding approach to software development. By embracing TDD, you can write cleaner, more maintainable, and ultimately more reliable code.

Podcast link: https://podcast.pythontest.com/episodes/76-tdd-don-t-be-afraid-of-test-driven-development-chris-may

From the blog CS@Worcester – Site Title by Iman Kondakciu and used with permission of the author. All other rights reserved by the author.