Category Archives: week-18

Week 18B – C Testing

For this week, I wanted to look at how different languages handle test cases, and I’ll continue with one I’m not the most familiar with, C! I’ve worked in small amount of C in classes at Worcester State, but have little experience outside of that. I feel like this is a good topic to discuss as knowing how other programming languages handle unit testing would be a great way to expand my knowledge when it comes to furthering my understanding of it within Java.

If you haven’t already read my other blog post on Python testing, feel free to read it right here!

For learning about unit testing in C, I consulted this article on the subject: https://interrupt.memfault.com/blog/unit-testing-basics

It seems like unit testing in C is a lot more barebones compared to Java, which in my experience utilizing C, makes sense for the language. A lot of features primarily used in Java, like object-oriented structures aren’t available in C (to my understanding, could totally be wrong).

For one major aspect, there seems to be only one assertion command in C, just simply “assert”. Theres no assertTrue, assertFalse, assertThrows, or assertEquals, just simply “assert”. And from the example given below:

#include <assert.h>

// In my_sum.c
int my_sum(int a, int b) {
  return a + b;
}

// In test_my_sum.c
int main(int argc, char *argv[]) {
  assert(2 == my_sum(1, 1));
  assert(-2 == my_sum(-1, -1));
  assert(0 == my_sum(0, 0));
  // ...
  return(0);
}

It seems the “assert” function comes from the <assert.h> library, much like the JUnit librarys used in Java. But more importantly, it seems that “assert” is the equivalent of “assertEquals”.

It also seems like Unit Testing in C is best implemented with tools outside of a compiler for C. The ones mentioned in the article in specific were CppUTest, Unity, and Google Test. For the rest of the article, the use examples using CppUTest. It was interesting to hear one of the options being called Unity, which is the name of a game engine, which, while not written in C, is written in a mixture of C# and C++, which are both offshoots of C. Makes me wonder how testing in a gaming engine works, perhaps it’s something to look at in a future blog post, hint hint, wink wink.

CppUTest seems to implement the same SetUp() and Teardown() functions that JUnit can employ, which is really good, as these methods are important for testing multiple methods. It also seems to have more then just an Equals assertion, even though the example used is another equals example.

This gets me more interested in C, as I have been told understanding C allows you to understand other languages much more clearly. Perhaps I’ll take a deeper dive some day, who knows! Until next time, my readers~!

From the blog CS@Worcester – You&#039;re Telling Me A Shrimp Wrote This Code?! by tempurashrimple and used with permission of the author. All other rights reserved by the author.

Week 18A – Python Testing

For this week, I wanted to look at how different languages handle test cases, and I’ll begin with the one I’m the most familiar with, Python! I’ve worked with Python in small amounts in the past, and have an understanding a lot of it’s syntaxes are similar to java’s, albeit simpler. I feel like this is a good topic to discuss as knowing how other programming languages handle unit testing would be a great way to expand my knowledge when it comes to furthering my understanding of it within Java.

For this, I’ll be looking at the official page for unittest on Python’s website, here:

https://docs.python.org/3/library/unittest.html

Right off the bat, I’m really interested in the fact that unittest is actually based directly off of JUnit! Which means a lot of the syntax, formatting, and framework is quite similar, just modified to fit the mold of Python.

Looking at the snippet they gave as an example…

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

In this, it seems the way you define test blocks is by having a class with (unittest.testcase) and then doing “def” to define each test case.

Even the assertions are the same and written near identically, as the first three use assertEqual, which is identical to javas assertEquals, minus the s, and assertTrue and assertFalse, which are also identical to their java counterparts. assertRaises, which is used in the third test, seems to be Python’s equivalent to assertThrows, however, it seems to be a bit different in comparison. assertRaises seems to identify a specific kind of exception being raised, whereas assertThrows would just identify any exception in general.

The last line also is a block of code that allows an easy way to run all the tests, so when you run unittest.main() in a command line, it will automatically run all the tests and display the results.

There also seems to be a whole bunch of different command line options to display results and modify the ways in which its run. As an example, theres “-v”, which stands for verbosity, much like the bash command, which shows the results of each individual test being run, like below:

test_isupper (__main__.TestStringMethods.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split) ... ok
test_upper (__main__.TestStringMethods.test_upper) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

It seems extremely interesting and makes me want to learn more Python, which would definitely help me in my career in all sorts of ways! Next blog we will be looking at how unit testing works in C. Until then!

From the blog CS@Worcester – You&#039;re Telling Me A Shrimp Wrote This Code?! by tempurashrimple and used with permission of the author. All other rights reserved by the author.

7 Steps to a Great Software Tester

Introduction: Enhancing your software testing skills requires a strategic approach encompassing organization, communication, clarity, and a positive mindset. In this guide, we’ll explore seven steps to elevate your testing capabilities and contribute effectively to your team’s success.

Step 1: Organize Everything

  • Organize your testing details to avoid missing important information.
  • Utilize a structured method to store communication and project details for easy access and reference.
  • Keeping all pertinent information in one place ensures clarity and helps in forming a cohesive testing strategy.

Step 2: Write Detailed Bug Reports

  • Craft clean and detailed bug reports to assist your team members and developers effectively.
  • Emphasize detail, clarity, and relevance in bug report writing.
  • Ensure bug reports are comprehensive yet concise, avoiding unnecessary information.

Step 3: Write Clear Test Cases

  • Clear and concise test cases are crucial for effective software testing.
  • Focus on clarity and simplicity in test case creation to facilitate efficient execution by your team members.
  • Optimal test cases typically range between 3-8 steps, minimizing the likelihood of errors during execution.

Step 4: Take Part and Communicate

  • Testing is a collaborative effort; involve all team members from the outset to enhance efficiency.
  • Keep the entire team informed and engaged to ensure a thorough understanding of project goals and requirements.
  • Early involvement and clear communication minimize risks, delays, and misunderstandings.

Step 5: Ask Yourself Questions

  • Testing involves decision-making and problem-solving; ask pertinent questions to guide your testing approach.
  • Clarify the objectives of your tests and select appropriate testing techniques to achieve desired results efficiently.
  • Refine your testing process by filtering out less relevant techniques and focusing on those that align with project goals.

Step 6: Maintain a Positive Mindset

  • A positive mindset significantly impacts testing outcomes; approach testing with optimism and determination.
  • Believe in your ability to uncover critical bugs and contribute positively to the project’s success.
  • Positivity is contagious and can inspire your team members to perform at their best, enhancing overall testing efficiency.

Step 7: Don’t Test Initially

  • Before diving into testing, take time to explore the application and understand its goals and features.
  • Familiarize yourself with the intricacies of the application to plan an efficient and effective testing strategy.
  • Align your testing goals with the objectives of the application to deliver impactful results.

Reflection: Each step emphasizes not only technical proficiency but also collaboration and strategic thinking. I’ve seen improvements in my testing approach, including clearer bug reports, more efficient test case creation, and enhanced teamwork. Moving forward, I intend to refer back to these seven steps before revieing or testing anything.

Conclusion: By following these seven steps, you can enhance your testing skills and make significant contributions to your team’s success. Embrace organization, communication, clarity, and a positive mindset to elevate your testing capabilities and achieve optimal results in your software testing endeavors.

Source – https://testlio.com/blog/how-to-be-an-efficient-software-tester/

From the blog CS@Worcester – CS: Start to Finish by mrjfatal and used with permission of the author. All other rights reserved by the author.

Security Testing

Introduction: In today’s digital age, where cyber threats loom large, ensuring the security of software systems and applications is paramount. Security testing emerges as a crucial practice in safeguarding sensitive data and resources from potential intruders. As I delve into the realm of security testing, I aim to explore its multifaceted nature and understand its significance in the realm of software development.

Selected Resource: The selected resource, an article from GeeksforGeeks, provides a overview of security testing, covering its goals, principles, focus areas, types, advantages, and disadvantages.

Focus Areas in Security Testing:

  • Authentication and Authorization: Testing the system’s ability to properly authenticate and authorize users and devices.
  • Network and Infrastructure Security: Testing the security of the system’s network and infrastructure, including firewalls, routers, and other network devices.
  • Application Security: Testing the security of the system’s applications, including testing for cross-site scripting, injection attacks, and other vulnerabilities.
  • Data Security: Testing the security of the system’s data, including testing for data encryption, integrity, and leakage.
  • Compliance: Testing the system’s compliance with relevant security standards and regulations.

Types of Security Testing:

  • Vulnerability Scanning: Automated scanning to detect known vulnerability patterns.
  • Security Scanning: Identification of network and system weaknesses, followed by solutions for risk reduction.
  • Penetration Testing: Simulation of attacks from malicious hackers to identify potential vulnerabilities.
  • Risk Assessment: Analysis of security risks in the organization, classifying them into low, medium, and high categories.
  • Security Auditing: Internal inspection of applications and operating systems for security defects.
  • Ethical Hacking: Exposing security flaws in the organization’s system through controlled hacking attempts.
  • Posture Assessment: Combining security scanning, ethical hacking, and risk assessments to provide an overall security posture.

Vulnerability in Security Testing:

  • Vulnerabilities are weaknesses in a system that could be exploited by attackers to compromise its security.
  • Identification of vulnerabilities is a crucial aspect of security testing to prevent potential breaches.
  • Types of vulnerabilities include SQL injection, cross-site scripting, misconfigurations, and weak authentication mechanisms.

Advantages and Disadvantages:

  • Advantages:
    • Identifying vulnerabilities
    • Improving system security
    • Ensuring compliance
    • Reducing risk
    • Improving incident response
  • Disadvantages:
    • Resource-intensive nature
    • Complexity
    • Limited testing scope
    • False positives and negatives
    • Time-consuming

Reflection and Future Application: Reflecting on the content of the resource, I gained a deeper understanding of the intricate layers involved in security testing, particularly in identifying vulnerabilities. In my future practice, I envision applying the knowledge gleaned from this resource to bolster security measures in software development projects. By integrating robust security testing protocols and leveraging advanced tools and techniques, I aim to enhance the resilience of systems and applications against potential vulnerabilities and threats.

Conclusion: In conclusion, security testing emerges as a cornerstone in ensuring the integrity, confidentiality, and availability of software systems and applications. By embracing a comprehensive approach to security assessment and staying abreast of emerging threats and technologies, we can fortify defenses and navigate the evolving landscape of cybersecurity with confidence and resilience.

Source – https://www.geeksforgeeks.org/security-testing/

From the blog CS@Worcester – CS: Start to Finish by mrjfatal and used with permission of the author. All other rights reserved by the author.

Elevating Code Reviews: Practical Tips for better Collaboration

Code reviews are a vital part of the software development process, serving as a checkpoint to ensure quality, foster knowledge sharing, and mitigate future issues. Drawing on practical advice from a stack overflow blog article (found here) this post explores how to elevate the practice of code reviews, enhancing their effectiveness and the collaborative environment they create.

Summary

The article from stack Overflow provided insightful tips on improving code reviews, emphasizing the importance of constructive communication and efficient processes. It suggest setting clear goals for reviews, such as catching bugs, ensuring consistency, and mentoring junior developers. Techniques like keeping comments clear and actionable, prioritizing empathy and understanding, and maintaining a balance between criticism and praise are highlighted as crucial for productive reviews.

Reason for selection

I chose this article because effective code reviews are essential for any development team aiming to produce high-quality software. As our coursework often involves collaborative projects and peer reviews, applying these enhanced practices can significantly benefit our collective learning and project outcomes.

Adding to the reasons for selecting this article, another compelling aspect is its relevance to the ongoing discussions in our software development courses about maintaining high standards in coding practices. As someone who has been part of several projects and observed firsthand the impact of well-conducted code reviews, I recognize the value in learning and sharing effective review techniques. This article not only enhances our understanding of best practices but also equips us with the tools to implement them effectively in our work, making it an invaluable resource for any aspiring software developer eager to improve their craft and contribute positively to team projects.

Personal reflection

Reflecting on the article, I appreciated the emphasis on empathy and clarity in communication. In past group projects, I’ve seen how negative feedback can demotivate peers, whereas constructive and positive communication can enhance team dynamics and improve code quality. This article reinforced the idea that code reviews are not just about finding errors but also about building a supportive team culture.

Application in future practice

Armed with these enhanced practices, I plan to apply the article’s recommendations in upcoming projects, particularly those involving teamwork. Emphasizing clear, empathetic feedback and leveraging tools for automating mundane aspects of code review will allow me and my peers to focus on more complex issues, thus improving our efficiency and the quality of our work.

Conclusion

Effective code reviews are more than just a quality assurance step; they are a cornerstone of a collaborative and learning-focused development environment. The tips provided by the Stack Overflow article offer valuable guidance on making good code reviews even better, ensuring that they contribute positively to both project outcomes and team dynamics. As we continue to engage in more collaborative projects, these practices will be essential in shaping how we approach code reviews and interact as a development team.

resources

https://stackoverflow.blog/2019/09/30/how-to-make-good-code-reviews-better/

From the blog CS@Worcester – Josies Notes by josielrivas and used with permission of the author. All other rights reserved by the author.

The Deadly Sins of Mobile Testing

To round out my semester, before beginning my summer research opportunity, I looked into extraneous material for my classes as I finish up. In looking for a blog for the final week of finals, I went with something more akin to basic general information regarding testing. I selected an article based around the common mistakes or sins in mobile testing. This connected with my most recent final project for another class regarding mobile development. I struggled to test my project for this class, and I am sure I committed many of these sins. The article’s title is Five Sins of Mobile Testing by Josh Galde

This article is quite dated, and Galde begins with describing the demand for mobile devices, which has since skyrocketed. Companies at the time aimed to expand their web presence to mobile platforms, but often overlooked the constraints, leading to rushed development and potential errors. This is something I experienced in my own project, having trouble with the visual aspect of app development. The necessity to develop multiple versions of the same app to accommodate different devices and configurations. Is something of an issue outlined by Galde, and one I experienced when switching between different size devices. This is similar to a non-responsive website in web development. Glade explains that to create successful, user-friendly, and reliable mobile apps, we should follow the best practices and avoid common mistakes, or “sins,”. The first sin is relying solely on emulation software, as problematic because emulators can’t fully replicate real device behavior, especially with carrier networks.This is something I experienced through only emulator testing. The second sin is using jail broken devices, which can alter their functionality, leading to inaccurate testing results. The third sin is not utilizing automation. Automated testing can save time and reduce errors by efficiently handling the repetitive testing process across multiple devices and platforms, which might be tedious to do individually. The fourth sin is ignoring the need to support internal apps. This can be a dangerous error for applications developed for businesses, as it ignores the possibility of employees or members utilizing their own devices for organization apps. And one of the most egregious, and fifth sin is skipping testing on real devices. This is a common but risky practice, rushing app development without thorough testing. This can lead to catastrophic failures in the app. Proper testing is critical to ensure app reliability and success.

At the end of the semester, reflecting on my learning is paramount to actually achieve a change in how I think. My final project presentation just ended a week ago, and already I reflect on mistakes and poor practices to improve going forward. These sins are many I have committed and will now avoid going forward to improve as a programmer.

Source:https://www.stickyminds.com/article/five-sins-mobile-testing

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

Week-18 Post

My second post this week will recover the three elements of unit testing: Boundary Value Testing, Equivalence Class Testing, and Decision Table-Based Testing. Each play a crucial role in validating software behavior and functionality. Boundary Value Testing focuses on the edges of input ranges. This technique identifies defects at the boundaries of input domains, where errors are most likely to occur. By testing the minimum, maximum, and edge values, testers can catch issues that might arise from off-by-one errors or other boundary-related bugs. This method is particularly effective because boundary conditions are common sources of defects in software applications. To utilize boundary value testing, first determine the minimum and maximum values for each input field, and second create test cases that include the boundary values (e.g., minimum, maximum, just inside, and just outside the boundaries).

Equivalence Class Testing divides input data into equivalent partitions, or classes, where test cases are expected to produce similar results. Instead of testing every possible input, testers select representative values from each class, significantly reducing the number of test cases needed. This method ensures that different inputs within the same class are treated equally by the software, helping identify any inconsistencies or unexpected behaviors across various input ranges. To utilize equivalence class testing, first group input values that are treated similarly by the system into classes, and second choose one representative value from each class for testing.

Decision Table-Based Testing involves creating a table that maps different input conditions to their corresponding actions or outputs. This technique is especially useful for testing complex business logic and decision-making processes. By systematically covering all possible combinations of inputs and their respective outcomes, decision tables help ensure that all scenarios are accounted for and validated. This method enhances the thoroughness of testing by providing a clear and structured approach to handling diverse input conditions. To utilize decision table-based testing, first list all possible conditions (inputs) and actions (outputs), and second create a table with all possible combinations of conditions and their corresponding actions.

Boundary Value Testing, Equivalence Class Testing, and Decision Table-Based Testing are powerful techniques that enhance the effectiveness and efficiency of software testing. These testing techniques help ensure that software applications are robust, reliable, and capable of handling various input scenarios effectively. By incorporating these methods into your testing strategy, you can enhance test coverage, identify potential issues early, and deliver high-quality software that meets user expectations and business requirements.

Blog Post: https://celestialsys.com/blogs/software-testing-boundary-value-analysis-equivalence-partitioning/

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.

continuous integration

For my final blog post for my Software Testing course, I wanted to go over something that also ties with other projects I’ve been working on during this semester in some way. In our Softawre Development Capstone team, we’ve had a couple of issues where we’ve had to touch upon the Thea’s Pantry continuous integration system through GitLab to have linter tests run automatically when pushing commits, so that commits that don’t match up to specification, the pipeline fails and the person who pushed those changes gets notified to fix any issues that arise. In this post, I want to go over a bit more detail about what continuous integration is and how it’s useful for developers.

According to Stephen Roddewig’s blog post on HubSpot, contiguous integration is an approach to development where code changes are regularly merged into a shared repository, built into a test application automatically, and the results of running this test application go back to the developer if any bugs or defects are found.

In practice, a continuous integration tool typically is an automated system where the source code is compiled with tests being automatically run on every individual push from a developer. This means that the developer’s contribution to the project is automatically tested on push, then either pushed forward to the maintainers or pushed back as a result of a pipeline failure.

The benefit of this is clear: bugs are caught quicker, the source code is updated on a regular basis with greater confidence because of the automated tests, and the pipeline provides an explicit and clear vision of what the specifications are for the project.

While working with the Thea’s Pantry system for my capstone, I could see these benefits in action. If a developer forgets to run tests locally (in the case of the Thea’s Pantry system, all tests are run in a script, and linters are run in their own script as well), the pipeline will catch any problems seamlessly, and the developer can easily see the pipeline failure, look at the output on GitLab, and determine what they need to fix in their branch.

In addition, it clarifies the specifications of what commits should look like, and what code should look like as well, on the basis that you can even add linters to the pipeline. It’s very useful in case someone forgets that we use conventional commits to have our changes be more clear with what they do, as the pipeline will detect that and function as a reminder of what things should look like.

All around, continuous integration is always a benefit for everyone involved in the software development process, creating a smooth system for testing that functions automatically rather than requiring developers to remember to run tests so they don’t mess up their branch.

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

Pairwise Testing

The blog post titled “Pairwise Testing: A Complete Guide” by Rajkumar (https://www.softwaretestingmaterial.com/pairwise-testing/) delves into the concept of pairwise testing, also known as all-pairs testing. I chose this blog because of its in-depth examples of  how to implement pairwise testing. These examples really made it easier to understand how pairwise testing can be used to reduce the amount of test cases while still maintaining high test coverage. The post also outlines the importance of pairwise testing and its advantages. Additionally, it compares pairwise testing with other testing techniques, highlights tools available for automating pairwise testing, and discusses its application in various scenarios.

Pairwise testing is a black-box testing technique used to reduce the number of test cases while still maintaining high test coverage. By focusing on combinations of input pairs, pairwise testing ensures that all possible pairs of input parameters are tested at least once. For example, if you had a program that took three inputs, X, Y, and Z, pairwise testing would create test cases for each combination of input pairs: (X, Y), (X,Z), and (Y,Z). At first glance this may seem like you have to create a ridiculous amount of test cases, but by following the steps for pairwise testing you can see how quickly the number of test cases is reduced.

The first step of pairwise testing is to identify all of your input variables. Next list all possible values for each variable. Variables that have numeric values may be reduced to valid and invalid to begin reducing the number of test cases needed. Then, by creating a table content columns of each variable and its possible outputs, you can get a list of each test case. 

This blog’s examples use tables to illustrate how each test case is created by filling in each column one by one.

The example from the blog uses a bookstore and creates a table of every variable. In this example you can see how each pair of variables covers all unique combinations except the book category and enquiry. These variables only test fiction with valid and non fiction with invalid. The other columns fixed this by simply reversing the order of one of the test pairs, but doing this would create the same issue for another combination of variables. In this instance two more test cases are added to the list to ensure the unique combination of book category and enquiry.

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

Security Testing

Like my previous blogs about performance and AI tools, I wanted to discuss another area of software testing that covers a specific development aspect. I chose security testing because while performance and functionality are essential, we must ensure our applications are safe for their users. This blog post, “Security Testing: Types, Tools, and Best Practices,” by Oliver Moradov, will outline various aspects of security testing, its importance, and its methodologies.

Oliver’s blog starts by defining security testing, listing its main goals and principles, and providing an index for many other aspects of security testing. It stresses that security testing is a non-functional testing process that determines the resiliency of software from cyber-attacks and data breaches. Non-functional testing focuses on how the system works rather than if it works. The primary goals are identifying assets, threats, vulnerabilities, and risks and performing remediation. 

The blog then discusses the types of security testing, including penetration testing, application security testing, API security testing, and vulnerability management. It also covers security test cases, and security testing approaches such as black box, white box, and grey box testing. The blog finishes by discussing best practices in security testing, such as shifting security testing left, testing internal interfaces, and automating tests.  

 I felt the distinction between functional and non-functional testing was important to discuss. Knowing how our data or the company’s data is handled is much more important for security than making sure the software functions correctly. It could function perfectly within the development team’s parameters but still fail to protect the company’s and users assets. 

I found it interesting that black box, white box, and grey box testing are applied differently than how they’re typically used in unit testing. The fundamental uses are the same, limiting and granting information, but there is much more to be gained when using this method in security testing. Testing what a malicious hacker could do with limited or abundant details on the software would be critical to protecting our assets. It also highlights the difference between non-functional and functional because developers use box testing to determine how to make errors occur within the system. In contrast, security tests would use the system functionality itself to create a breach in security. 

The sections detailing what security vulnerabilities they look for were enlightening. The authentication, input validation, and application logic sections highlighted what scenarios the security tests may encounter to validate system safety. I’m glad the blog discussed tools for developers to ensure their code can’t be exploited. Overall, this blog gave plenty of rudimentary information on security testing, and I urge those interested to check it out. In the future, I plan on using the tools and testing techniques to ensure that my code is safe for its users and owners. 

Blog: https://brightsec.com/blog/security-testing/

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