Category Archives: Week-15

Apprenticeship Patterns: Prepetual Learning


 I find the assertion that one is never done learning to be very true
to life. One’s skills as a software developer should be iterated upon just
like the very programs we craft. The section on perpetual learning
provided  many interesting examples of ways to tackle improving one’s
own knowledge base and skillset. I want to cover some of my favorite
sections in this blog post and over the course of the next couple blog
posts.

Expand Your Bandwidth


I constantly get the feeling that my knowledge in my career is always much
shallower than it should be. The suggestions provided at the start with
Google Reader and following software luminaries seemed interesting, but I
was much more interested in looking at online courses and podcasts. I want
to be able to constantly expand my knowledge base and explore new
horizons.  This reminds me of when I was keeping up to date with a
subreddit that was all about mesh networks and peer-to-peer computing. It
sprung up in the aftermath of network neutrality being struck down, and a
lot of people on there were proposing creating a giant open source mesh
network to combat predatory internet service providers. It had the overly
ambitious goal of decentralizing the internet which ,suffice to say, has not
come to pass yet, although I’ve heard that the emergent Web 3.0 is supposed
to be it. I was fascinated by the ingenuity of using a bunch of Raspberry
Pis to create mesh networks all around a city. I want to reignite some of my
passion for obtaining new knowledge and explore what is new today. I know
A.I. has gotten a lot of publicity, to the point of becoming something like
a buzzword, but I want to see what the other sectors of the tech industry
are working on. Thanks to writing this blogpost I went and looked to find
new sources of information. I even started perusing reddit, specifically in
the technology and programming tag,  again to search for any new and
interesting developments. I have already checked out the r/webdev amd
r/learnprogramming for some tips.


From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Regression Testing


  While looking for something that I could use for my 5th homework, I started
looking into other software testing styles that we have not covered in
class. There are tons of different styles that are implemented to introduce
quality testing to software development. One such style I found this time is
called regression testing, a testing style created to combat resurfacing
bugs. Basically, regression testing is about implementing test cases every
update, and maintaining them throughout future iterations. This is done to
prevent old bugs from resurfacing and to check for any new bugs from being
introduced in every update. Test cases should be created and implemented
after every iteration to prevent bugs from piling up within your
software.


https://www.browserstack.com/guide/regression-testing



 While this may sound a lot like retesting , the main difference is
that regression testing looks for unknown bugs rather than known. How this
may look is the test cases are not for any specific bug but rather more
general to catch any problems that came about during the last change. Other
differences include the fact that regression testing can be automated, while
Retesting cannot. In order to remain vigilant, one should implement both of
these styles in order to avoid any problems from implementing new
changes.


https://www.browserstack.com/guide/retesting-vs-regression-testing


Some examples that I saw listed of regression testing tools include
Cypress, Playwright, and Puppeteer. These tools typically ensure that your
software and test cases work across different platforms and operating
systems. Last post I talked about how I found a website that uses A.I. to
write test cases, and considering how regression is already inclined to be
automated, I can’t help but wonder how long we have until we see an entirely
automated software development pipeline using regression testing. I think
it’s not too far in our futures.



In the article I linked above they give some examples of some regression
test cases. They use the classic shopping cart program and the test cases
are things like making sure the back end fetches the correct number of items
in the cart, or checking if the elements on the front end are still visible
despite scrolling down. These cases are general enough to catch both new and
old bugs on subsequent updates. For the Mars Rover kata we did in class an
example I could use would be updating the grid to be 100 squares big in each
direction, and then creating a new test case to check if it still wraps
around at the 99 mark.


 

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Regression Testing


  While looking for something that I could use for my 5th homework, I started
looking into other software testing styles that we have not covered in
class. There are tons of different styles that are implemented to introduce
quality testing to software development. One such style I found this time is
called regression testing, a testing style created to combat resurfacing
bugs. Basically, regression testing is about implementing test cases every
update, and maintaining them throughout future iterations. This is done to
prevent old bugs from resurfacing and to check for any new bugs from being
introduced in every update. Test cases should be created and implemented
after every iteration to prevent bugs from piling up within your
software.


https://www.browserstack.com/guide/regression-testing



 While this may sound a lot like retesting , the main difference is
that regression testing looks for unknown bugs rather than known. How this
may look is the test cases are not for any specific bug but rather more
general to catch any problems that came about during the last change. Other
differences include the fact that regression testing can be automated, while
Retesting cannot. In order to remain vigilant, one should implement both of
these styles in order to avoid any problems from implementing new
changes.


https://www.browserstack.com/guide/retesting-vs-regression-testing


Some examples that I saw listed of regression testing tools include
Cypress, Playwright, and Puppeteer. These tools typically ensure that your
software and test cases work across different platforms and operating
systems. Last post I talked about how I found a website that uses A.I. to
write test cases, and considering how regression is already inclined to be
automated, I can’t help but wonder how long we have until we see an entirely
automated software development pipeline using regression testing. I think
it’s not too far in our futures.



In the article I linked above they give some examples of some regression
test cases. They use the classic shopping cart program and the test cases
are things like making sure the back end fetches the correct number of items
in the cart, or checking if the elements on the front end are still visible
despite scrolling down. These cases are general enough to catch both new and
old bugs on subsequent updates. For the Mars Rover kata we did in class an
example I could use would be updating the grid to be 100 squares big in each
direction, and then creating a new test case to check if it still wraps
around at the 99 mark.


 

From the blog CS@Worcester Alejandro Professional Blog by amontesdeoca and used with permission of the author. All other rights reserved by the author.

Increasing Code Fortification: A Guide to Security Testing in JUnit 5

In the ever-evolving landscape of software development, ensuring robust security measures has become paramount. With the increasing frequency and sophistication of cyber threats, developers must incorporate stringent security testing protocols into their workflows to fortify their code against potential vulnerabilities. One such indispensable tool in the developer’s arsenal is JUnit 5, a powerful testing framework for Java. In this blog post, we delve into the realm of security testing in JUnit 5, exploring its significance, methodologies, and best practices.

Understanding Security Testing in JUnit 5

Security testing in JUnit 5 involves the systematic examination of code to identify and rectify security vulnerabilities. Unlike traditional testing, which primarily focuses on functional correctness, security testing scrutinizes the codebase for potential exploits and weaknesses that could be exploited by malicious actors.

Methodologies for Security Testing in JUnit 5

  1. Static Code Analysis: Static code analysis tools such as FindBugs and SonarQube play a pivotal role in identifying security vulnerabilities in the codebase even before execution. By analyzing the code’s structure and logic, these tools can flag potential security loopholes, ranging from injection vulnerabilities to insecure data handling practices.
  2. Input Validation Testing: Input validation is a crucial aspect of security testing, especially in web applications susceptible to injection attacks. In JUnit 5, developers can write test cases to simulate various input scenarios, ensuring that the application robustly validates user inputs to prevent injection attacks like SQL injection and cross-site scripting (XSS).
  3. Authentication and Authorization Testing: Authentication and authorization mechanisms are integral components of secure software systems. JUnit 5 facilitates the creation of test suites to evaluate the effectiveness of authentication mechanisms, ensuring that only authorized users can access sensitive functionalities and resources.
  4. Security Configuration Testing: JUnit 5 allows developers to test security configurations, such as HTTPS settings, encryption algorithms, and access control policies. By meticulously examining these configurations through test cases, developers can identify misconfigurations and strengthen the overall security posture of the application.

Best Practices for Security Testing in JUnit 5

  1. Comprehensive Test Coverage: Aim for comprehensive test coverage to ensure that all critical components and functionalities are thoroughly evaluated for security vulnerabilities.
  2. Regular Regression Testing: Incorporate security tests into your regression testing suite to detect regressions that could reintroduce previously patched vulnerabilities.
  3. Utilize Mocking and Stubbing: Leverage mocking frameworks like Mockito to simulate external dependencies and stub out sensitive operations, allowing for isolated and controlled security testing scenarios.
  4. Continuous Integration and Delivery (CI/CD): Integrate security tests into your CI/CD pipeline to automate the testing process and identify vulnerabilities early in the development lifecycle.

Conclusion

Security testing in JUnit 5 is an indispensable practice for safeguarding software applications against malicious threats. By employing rigorous testing methodologies and adhering to best practices, developers can bolster the security posture of their codebases, thereby mitigating the risks associated with cyber attacks. Embrace security testing as an integral part of your development workflow, and fortify your code against potential vulnerabilities.

For further insights into security testing in JUnit 5, explore the official JUnit 5 documentation here. Additionally, delve into static code analysis tools such as FindBugs here and SonarQube here.

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

Mutation Testing

A topic we touched upon in class for a tiny bit was mutation testing. It is a different kind of software testing, where it alters your code and then runs your tests. If your tests fail, that means your tests are good. If your tests pass, that means your tests are not good. The altered versions of the code are called mutants, and if they are caught by the tests, as in failed, they are considered killed. If they pass, they are considered to have survived. The concept is strange, but can be effective, especially in finding inaccurate tests or seeing if you have enough tests.

In this blog post, Uncle Bob talks about his experience with mutation testing, how he came upon it, some benefits and how it works. He starts off by stating some issues with unit testing, such as writing enough tests, covering every line, branch, or path, and whether or not a test will fail depending on if you change some code. He answers these issues with sufficiency, coverage, and semantic stability, all of which can be solved by using mutation testing. It is fairly simple to run, and there is multiple ways to go about it. You run pitest tool, which alters your code a little bit, such as inverting if statements. It will do this more than once, where each variation of your code is a mutant. Then, for each mutant, it will run through all of your tests. If the tests fail, the mutant is killed, and if the tests pass, the mutant survived. Ideally, you want all of the tests to fail, which may be difficult to wrap your head around, typically you want your tests to pass. Having mutation testing is just another layer of testing to ensure your code is working properly. If a mutant survived, a number of things could have happened, such as ignored tests or discipline became too relaxed and people started writing sloppy code. Either way, it’s a good way to reinforce your tests and code. 

We did not really get to play around with this a lot in class, but it was cool to see how it worked. It had created multiple batches of mutants and might have ran the tests individually, but I may be wrong about that. If we had the chance to run it on code that we wrote, or if I had ran it on code that I wrote, maybe I could have understood it more. I will definitely use this in the future.

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

CS-443: Week 15

Performance Testing

Performance testing is the process of evaluating how a system performs under specific workloads. Responsiveness and stability of the system is monitored by examining the speed, reliability, and application size. Common indicators that are used for testing are network response times, number of users the system can handle at a time, processer memory consumption, and more.

Performance testing is an important part of the software development process. If an application is not tested before being released, users may have a negative experience because of errors that could have been found in the performance testing phase. Users that have a negative experience may be deterred from using the application in the future resulting in fewer overall users. Performance testing aims to find these errors before release, so users can have the best possible experience

When is performance testing done?

In software development, there are two main phases: development and deployment. Development testing focuses on individual components such as web services, APIs, and microservices. The earlier development testing begins, the earlier errors can be caught. Catching these errors early in the development phase is important because as the code base progresses, there is more and more code building on top of code that may have errors. This can make fixing the error more complicated. As the application becomes larger, comprehensiveness of the tests should also scale alongside. However, the application may get to a point where testing in the development phase becomes unreasonable and testing is done during the deployment phase. This happens when testing involves replicating a production environment, but recreating the environment is too difficult or expensive.

Types of Performance Testing

There are many types of performance testing that are done throughout the development process to verify the application performs as expected and can meet user requirements. Some of these performance testing types are:

  • Load Tests – Tests the application under a realistic load by simulating virtual users. Response times are monitored, which can reveal potential bottlenecks to the system’s performance.
  • Stress Tests – Similar to Load Tests, but the number of simulated virtual users is greatly increased. This is to see how the application runs when under peak activity.
  • Soak Tests – Tests are conducted over an extended amount of time, as opposed to the tests mentioned above. This test is to evaluate how the system performs when under intense loads for a prolonged amount of time.

Conclusion

This article was chosen because it covered a variety of topics within performance testing, so I was able to gain a general understanding of what performance testing is. Performance testing is an important process in software development because it finds potential weak spots in a system. These weak spots can come from slow response times during peak activity, long load times, etc. Therefore, performance testing should be done on all systems to improve the user experience. In the future, I intend to look further into performance testing tools and frameworks to see how I can implement them in later projects.

Resources:

https://www.tricentis.com/learn/performance-testing

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.

Nurture Your Passion

The Nurture Your Passion pattern is about how important it is to protect and grow your passion for software craftsmanship even in some environments where it might not be supported. This pattern also talks about the challenges that people as software developers face in certain environments where their passion for the craft isn’t supported. Not only does it acknowledge the challenges faced by software developers in environments that may not fully support their passion but also provide strategies to navigate and thrive in those situations. Use certain strategies to protect and nurture your passion by working on what you like and drawing your own career path. The pattern shows that the real challenges that software developers face are when their passion for coding isn’t given its due, so they use a strategy to make their work more passionate. I felt like this pattern emphasizes preserving passion when a challenge comes around and finding a nurturing environment for that passion in software development. It’s great advice to work on tasks that interest you and also make sure to look for supportive people who like your ideas to motivate your success. It’s changed the way I think about my career path and how I should go about challenges in that journey, it’s important to be passionate about work but if it doesn’t give you a purpose or challenge you it’s important to find something that does.

 This pattern wants to encourage people to make sure that their career path has a purpose and that they’re passionate about it. It makes me want to be part of an environment that fits my values even if challenging. It’s not just about writing code; it’s about making sure every step in your career journey feels meaningful. seeking out a workplace that aligns with your values, even if it means tackling some tough challenges along the way. This pattern is a reminder that staying driven and having a clear sense of purpose in your career is everything, even when the going gets tough. This pattern wants to remind people of the importance of maintaining enthusiasm and purpose in one’s career path,  even though it comes with some challenges. It encourages self-care, learning, and engagement that can help in long-term success and satisfaction in software craftsmanship.

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.

System Testing

The three levels of the software testing process are unit testing, integration testing, and system testing.
Unit testing tests the isolated functionality of each individual unit. 
Integration testing tests the functionality of combining units to ensure they work together as intended. 
System testing tests the software as a whole. 

In my reading about integration testing, I noticed that at some point during this testing phase the system should be tested as a whole. Is system testing just a redundant and more in depth testing methodology focused on this? Sean Coughlin answers this question in his blog “Understanding System Testing in Software Engineering” (https://blog.seancoughlin.me/understanding-system-testing-in-software-engineering) by providing a clear understanding of what system testing is and what it tests for. 

System testing is a software testing phase that assesses a fully integrated software system’s compliance with requirements, covering both functional and non-functional aspects. These non-functional aspects are what makes system testing so comprehensive compared to integration testing when testing the software as a whole. Examples of non-functional testing include; performance testing, security testing, and usability testing.

Coughlin uses an e-commerce website as an example to illustrate system testing and each of its components. Functional testing ensures each feature of the website works as intended, Performance testing ensures the website still works even during peak user times. Security testing ensures the website is robust against cyber threats and that data is handled correctly. Usability testing ensures the website is user-friendly across multiple platforms.

Testing frameworks exist that allow for automated test such as simulating heavy loads for performance testing. User testing on the other hand is typically done manually as it focuses on a user’s experience. This means having a range of people, from developers to stakeholders, testing end-to-end use of the software. 

Overall system testing is testing an application for real world use. This goes much deeper than just functionality of the software. This is the last phase of testing before the software is released to the final product for acceptance testing. Meaning it is important that developers properly system test to identify and fix issues during this phase.

The scope for system testing is even larger than I could have imagined. Coughlin states, “I like to think of system testing as more of an umbrella term that captures lots of different testing forms.” which perfectly describes how system testing encapsulates testing all aspects of a software.

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

Pairwise Testing

Another important topic that we have discussed in CS-443, or Software Quality Assurance and Testing, is known as Pairwise Testing. Pairwise Testing is yet another form of testing, but this type is a little bit different than the rest. Pairwise Testing, sometimes known as all-pairs testing, tests each pair of input parameters in order to make sure that the functions in the system run correctly no matter what the input is, guaranteeing that it will run for every combination. Pairwise Testing is known as a Permutations and Combinations (P&C) based software testing technique. A blog that I found to be really helpful in explaining Pairwise Testing is known as Pairwise Testing | What It Is, When & How to Perform by Kiruthika D. In the blog, she gives an example that helped me understand more. She states “Let’s say you have an application that allows users to enter two numbers, and the application will output the sum of the two numbers. You can use pairwise testing to test all possible combinations of two numbers, such as (1, 2), (2, 3), (3, 4), (4, 5), etc. By testing all the combinations of two numbers, you can be sure that the application is working correctly and will not fail when given different numbers.” This shows that you don’t actually test every single combination, but you test every single input with another input. This way, it makes sure that all of the inputs work instead of testing a potentially infinite amount of combinations.

The actual purpose/use of Pairwise Testing is exactly what I previously stated. It is used to make sure that all combinations of inputs are possible, but you don’t need to test every single combination. It can be extremely helpful as it reduces the amount of time it takes to test the program as well as the amount of effort. While Pairwise testing is a great testing technique, you obviously can’t use it all the time as it involves pairs. As for when to use it, Kiruthika states “Pairwise testing is helpful when testing complex systems that have multiple input parameters and multiple possible values for each parameter. It can significantly reduce the number of test cases that need to be created while ensuring that all possible discrete combinations of parameters are tested. This can help reduce test case creation time and cost and improve the software’s overall quality. Pairwise testing is not appropriate for all types of software testing. As we discussed, it is most effective for systems with multiple parameters and multiple possible values for each parameter. If a system has only a few parameters and a small number of possible values for each parameter, pairwise testing may be unnecessary. Pairwise testing, also, will not be useful if the values of inputs are inappropriate.” Essentially she is saying that Pairwise testing is used for functions that have multiple parameters with multiple values, and the order of parameters doesn’t matter. On top of that, depending on the type of parameter, the technique might not work either. While I personally don’t see myself using this technique in the future, I think that it has the opportunity to be very useful in certain situations, so I’m glad that I was able to understand it more in case I ever need to use it.

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

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.

Unit Testing

For this week’s blog post, I decided to discuss the article “Unit Testing vs Test-Driven Development” by Albert Stec. I chose this article because it compliments the unit testing topic in the syllabus. This article discusses what unit testing is, why its important and how it fits into test driven development.

The first part of this article spends some time defining what a unit test is. Unit test is usually a method that validates a small portion of the source code. So, the unit test is a programmatically written, automatic test. The unit test takes the initial data, passes it to the code under test, and asserts if the execution result is the same as the expected result.” The article then goes on to discuss what a well designed unit test should have.

The five most important parts of writing a good unit test according to the author are that it is fast, isolated, deterministic, readable and simple. “As we can see it looks simple. Although writing efficient unit tests could be complicated depending on the code we want to test. A well-written unit test should be: 1: Fast. A single project can contain a big number of unit tests, even hundreds, or thousands. Moreover, unit tests can be executed often, e. g., while developing a new feature to avoid regression or in CI/CD pipelines. Therefore, they must run as fast as possible. 2: Isolated. A unit test shouldn’t modify or depend on any external state. 3: Deterministic. A unit test should always return the same result no matter how many times we execute it. Of course, if nothing is changed between runs. 4: Readable. Unit tests are code that needs to be maintained. Therefore, it should be clear and easily understandable. 5: Simple. Often we can read that the unit test should contain a single assertion. Although it can be discussable, the fact is unit tests should validate small portions of the source code.” The next part of the article discusses the importance of unit testing in regard to software development.

This last part of the article discusses how unit testing is important to unit testing development. “To write appropriate unit tests before the logic developers spend more time on analyzing and understanding the problem and its domain. Therefore, the code is more likely to meet all requirements and clients’ needs. It’s one of the most important aims of TDD. The cycles play an important role, as the tests become more specific with time while the implementation becomes more generic.”

Article: https://www.baeldung.com/cs/unit-testing-vs-tdd

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.