Category Archives: CS-443

Chapter 1 of “Apprenticeship Patterns” delves into the concept of the “Long Road” pattern.

The “Long Road” pattern underscores the importance of embracing the journey to mastery in software development rather than seeking quick fixes. It begins by emphasizing the complexity and depth of software development, stating that mastery is not achieved overnight. The pattern suggests committing to a lifelong journey of learning and improvement, recognizing that expertise requires time, effort, and dedication.

The chapter delves into the analogy of software development as a craft, comparing it to traditional crafts like woodworking or blacksmithing. It highlights the importance of embracing the iterative process of skill development, viewing each project as a chance to enhance abilities and deepen understanding. Additionally, it promotes a mindset of humility among practitioners, acknowledging that there is always more to learn and room for improvement.

One particularly intriguing and beneficial aspect is the focus on deliberate practice and intentional learning. The chapter highlights the importance of seeking challenges that expand one’s skills and actively soliciting feedback from experienced practitioners. It encourages the development of a personalized learning plan aligned with individual goals, promoting a proactive approach to skill enhancement.

Moreover, the chapter introduces the concept of “Kindling Your Enthusiasm,” which underscores the significance of retaining passion and curiosity in one’s profession. It proposes that nurturing a sense of wonder and excitement can bolster motivation and help individuals persevere through the challenges and setbacks they may face.

This chapter hasn’t fundamentally altered my perspective on my intended profession, as I already held the belief in continuous learning and growth. However, it serves as a reaffirmation of the significance of embracing the journey and dedicating oneself to lifelong improvement. It reinforces the understanding that expertise isn’t attained overnight but is rather the outcome of consistent effort and commitment.

Overall, Chapter One of “Apprenticeship Patterns” offers valuable insights into the mindset and approach crucial for success in software development. It highlights the significance of embracing the journey of mastery, engaging in deliberate practice, actively seeking feedback, and sustaining passion and enthusiasm. These principles are not limited to software development but can be applied to any profession or pursuit that demands continuous skill development and growth.

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

CS-448: Week 18

Security Testing

Security testing is an important part of software development and testing. Security testing focuses on identifying security vulnerabilities such as malicious attacks, unauthorized access, and data breaches. Testing is done by verifying the system is compliant with security standards, evaluating security features and mechanisms, and conducting penetration tests to find weaknesses.

Security testing plays a critical role in software testing for numerous reasons. Some of these include the protection of sensitive data, meets compliance requirements, and most importantly maintains trust. An application with strong security helps build trust among clients and end users because strong security makes users feel that they can use the application without their information being at risk to be compromised. Organizations are held to security standards that are used to regulate the minimum level of security in an application. Security testing can be used to identify security vulnerabilities and ensure the application meets the set standards.

Main types of security testing

There are many types of security testing based what the intended use is. For example there is security testing for software applications, web based applications, APIs, and more.

Application security testing tests the security of a software application. The process includes a combination of automated and manual testing techniques such as code analysis, penetration testing, and security scanning.

As the name suggests, web based application security testing focuses on identifying vulnerabilities in web based applications. Testing also involves a commination of manual and automated testing; however, what is actually tested differs from application security testing. This is because testing web based applications involves methods such as SQL injection testing, and cross site scripting testing.

API testing evaluates the security of an application’s APIs and the systems that the APIs interact with. When testing APIs, various types of malicious requests are sent to the APIs and their responses are analyzed to find potential vulnerabilities. APIs are susceptible to specific threats such as denial of service attacks, API injection, and man in the middle attacks. Man in the middle attacks are where an attacker intercepts the API communication to steal sensitive information. Therefore the goal of API security is to ensure that they are secure from attacks and sensitive information is protected.

Conclusion

This article was chosen because it clearly explained what security testing is, why it is important, and the different types of security testing. This was important to me because I have a very little knowledge/experience with security testing. I enjoyed learning about security testing as it plays an essential role in software development because no one wants to use an application where their information could be compromised. In the future I intend to look further into standard security measures, and how to test them.

Resources:

https://www.hackerone.com/knowledge-center/what-security-testing#:~:text=Security%20testing%20is%20an%20important,unauthorized%20access%2C%20and%20data%20breaches.

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.

Chapter 6 of “Apprenticeship Patterns,” introduces the concept of “Sweep the Floor”.

In Chapter 6 of “Apprenticeship Patterns,” introduces the concept of “Sweep the Floor” is introduced, highlighting the significance of humility and readiness to undertake even the simplest tasks as a way of learning and contributing effectively to a software development team.

The pattern starts by addressing the mistaken belief that novice software developers should concentrate solely on coding or tackling intricate challenges. Nevertheless, the authors contend that there’s considerable merit in tackling routine or seemingly unimportant tasks like documentation, testing, or tidying up code. Engaging in these activities offers chances to gain knowledge, grasp the project’s scope, and establish trust among team members.

The pattern advises apprentices to adopt humility and adopt a mindset where they are eager to contribute in any capacity, regardless of the task’s level of complexity or appeal. By undertaking modest, low-stakes duties, apprentices can incrementally bolster their self-assurance, broaden their exposure to various facets of software development, and exhibit their dedication to the team’s prosperity.


An intriguing facet of this pattern lies in its stress on the significance of context and comprehending the overarching objectives of the project or organization.
Through involvement in activities such as documentation or testing, apprentices can acquire a deeper understanding of the project’s needs, limitations, and obstacles, which can serve as valuable insights for their subsequent contributions and decision-making processes.

Additionally, the pattern underscores the importance of collaboration and teamwork within software development. By engaging wholeheartedly in all project facets, irrespective of their level of experience or expertise, apprentices can position themselves as indispensable team players and forge robust connections with their peers.

This pattern is useful because it provides a practical approach to learning and professional development for apprentices in software development. By promoting humility and a readiness to tackle even the simplest duties, it aids apprentices in constructing a strong groundwork of competencies, understanding, and connections within their teams. Furthermore, by actively contributing to the team’s achievements in diverse roles, apprentices can hasten their learning curve, amass invaluable experience, and eventually evolve into more proficient and esteemed members of the software development realm.

Ultimately, this pattern encourages a mindset that values practical proficiency, self-directed learning, and a commitment to continuous skill development. It can inspire me to approach me intended profession with a greater sense of agency, confidence, and readiness to tackle real-world challenges.

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

Sprint 3 Reprospective

Docker Build Pipeline:

  • Issue: Path not correct for copying files into Docker Compose container.
  • Solution: Adjust copy statements in Dockerfile to specify correct paths.
  • Implementation: Modify paths relative to Docker directory, e.g., bin/ if in src/.

Development Docker:

  • New scripts added for running and installing nodemon with package.
  • Type noderundev in shell script for consistency.

Reconfigure Pipeline:

  • Existing issue persists for team OL1.
  • Keep test.sh temporarily until linters are added to config.
  • Reporting system pipeline configure fails due to missing es.lint configuration file.

Linters Integration:

  • Linters not in repo for pipeline.
  • Documentation required for pipeline operation.
  • Branches cleanup ongoing.

Shell Scripts for Convenience:

  • Provide shell scripts in directories for ease of use.
  • Example: build/backend.dev for npmrundev.

Backend Development:

  • Start nodemon instead of rpm for backend changes.
  • Ensure nodemon reloads backend on code changes.

Scripts Management:

  • Separate scripts for dev and prod environments.
  • Create backenddevup.sh for backend development.
  • Later adjust for production environment.

Startup Procedures:

  • Determine startup procedure for MongoDB and RabbitMQ.
  • Currently, Docker runs MongoDB and RabbitMQ for production.
  • Scripts needed to start these services.

Research:

  • Update es.lint Docker image for better functionality.
  • Transfer existing config to new format for better linting.
  • Investigate linting for syntax and code errors.
  • Configure Gitpod workspace for linting and formatting.
  • Set up Gitpod.yaml for npm install and linting.

Code Formatting:

  • Utilize Prettier in pipeline for automatic code formatting.
  • Ensure neat documentation of all procedures.

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

Behavior-Driven Development

Behavior-driven development is a shift in software development practices, aiming to minimize feedback loops and better efficiency. This article explores BDD and its changes from usual waterfall models to feedback-driven methods. It emphasizes the connections between analysis, testing, coding, and design within a loop of continuous feedback, leading to more effective software development. As a student, understanding cutting-edge methods like BDD is crucial. I chose this resource to go more into the details of behavior-driven development, its principles, implementation strategies, and the benefits it offers in terms of efficiency and quality assurance. Behavior-driven development focuses on behavior, collaboration, and continuous improvement that follows my class’s ideas to develop great working software solutions. The source’s discussion on behavioral-driven development’s misconceptions, especially regarding its association with UI testing, was interesting. Looking ahead, I aim to use behavioral-driven development principles in my development workflow. By adopting a test-driven analysis approach, I want to gain a deeper understanding of system behavior, prioritize features effectively, and deliver value-driven software solutions. 

Behavior-driven development offers strong communication, a shorter learning curve, and high visibility. With the shared language it’s easier for everyone to have an understanding of the project development and BDD can reach a bigger audience. Since BDD is taught in a simple language it makes learning shorter and easier. This source has sparked a curiosity to explore behavior-driven development frameworks like Cucumber and Gherkin to articulate behavior-driven tests effectively. While dealing with behavior-driven development there are a ton of rules used to guide those principles. BDD is a little tough but with a lot of practice, this principle will allow people to master this skill. The journey through BDD’s principles, misconceptions, and real-world applications has been very interesting. I enjoyed reading about behavioral-driven development and how it works in software development. It has given me a deeper understanding of iterative development, collaboration, and user-centric design. Using a behavior-driven development approach to software development, I look forward to using its power to drive efficiency, quality, and customer satisfaction in my future projects. BDD isn’t just a method, it’s an idea that focuses on continuous learning, improvement, and innovation in software development.

https://semaphoreci.com/community/tutorials/behavior-driven-development

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.

AI in Software Testing: A Look at the Future

This blog post explores the growing influence of Artificial Intelligence (AI) in software testing, drawing inspiration from the podcast “AB Testing: All We Talk About is AI” (Episode 187: All We Talk About is AI).

The Rise of AI in Software Development

AI is transforming various aspects of software development, and testing is no exception. AI-powered tools are being utilized in several ways, including:

  • Automating Repetitive Tasks: AI can automate repetitive testing tasks, such as regression testing, freeing up human testers to focus on more complex scenarios and exploratory testing.
  • Generating Test Cases: AI can analyze user behavior and system data to automatically generate comprehensive test cases, ensuring thorough test coverage.
  • Defect Detection: Machine learning algorithms can be trained to identify bugs and defects in code with greater accuracy and efficiency than traditional methods.
  • Performance Optimization: AI can analyze performance data and suggest improvements to optimize software speed and responsiveness.

Impact on QA Professionals

While AI might seem like a potential replacement for human testers, it’s more likely to become a valuable tool in the QA toolbox. Here’s how:

  • Increased Efficiency: Automation of repetitive tasks allows QA testers to focus on higher-level testing strategies and leverage their expertise for more critical thinking and problem-solving.
  • Improved Accuracy: AI-powered tools can assist in catching bugs and defects that might be missed with manual testing alone, leading to higher quality software releases.
  • Faster Time to Market: By automating repetitive tasks and enhancing testing efficiency, AI can contribute to faster software release cycles.

The Future of QA with AI

The future of software testing is likely to see a deeper integration of AI, potentially leading to:

  • Self-Learning Testing: Imagine AI that can learn from its testing experiences and continually improve its strategies over time.
  • Context-Aware Testing: AI could analyze the context of a software application, such as its target audience or intended use, and tailor its testing approach accordingly.
  • Proactive Bug Prevention: AI might be able to predict potential issues before they even occur, allowing developers to address them early in the development cycle.

Challenges and Considerations

While AI offers significant benefits, it’s important to acknowledge the challenges as well:

  • Over-reliance on Automation: Overdependence on AI for all testing aspects should be avoided. Human expertise remains crucial for strategic thinking and creative test case design.
  • Explainability and Bias: AI algorithms can be complex, making it challenging to understand how they arrive at their conclusions. It’s vital to be aware of potential biases in AI models to ensure fair and unbiased testing practices.
  • The Human Element: The human touch will always be essential in QA. AI cannot replace the critical thinking, communication, and collaboration skills that are vital for successful software testing.

Conclusion

The rise of AI presents both challenges and opportunities for software testing professionals. By embracing AI as a valuable tool and continuously developing our skill sets, QA professionals can ensure they remain a critical function in the ever-evolving world of technology.

Take a look at the podcast: https://podcasters.spotify.com/pod/show/abtesting/episodes/Episode-187-All-we-talk-about-is-AI-e2a1sk4/a-aae4uv8

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

Path Testing: Your Guide to Unveiling the Hidden Bugs in Software

Welcome back, fellow coders! Today, I’m going back to a technique called path testing. 

Why is Path Testing Important?

Software development thrives on creating programs that function flawlessly, regardless of user interaction. Traditional testing methods might miss certain sections of code depending on user choices. Path testing, however, takes a different approach. It systematically executes every possible path a program can take, significantly increasing the likelihood of encountering and eliminating potential errors.

Here’s how path testing elevates your software development game:

  • Enhanced Bug Detection: Think of bugs like sneaky goblins hiding in the castle’s shadows. Path testing, by meticulously traversing every path, shines a light on these goblins, exposing them before they can cause problems for users.
  • Improved Software Quality: Just like a well-maintained castle provides a secure and comfortable environment, path testing leads to the creation of high-quality software. Identifying and rectifying errors early on ensures a more robust and reliable program.
  • Increased Confidence in Functionality: Having meticulously explored every potential path within the program, testers gain a heightened sense of assurance. They know, with greater confidence, that the program will perform as intended, leading to a more predictable and stable user experience.

Exploring the Different Levels of Path Testing

Path testing isn’t a one-size-fits-all approach. There are various levels of coverage, each focusing on a specific aspect of the program’s execution paths:

  • Statement Coverage: This foundational level resembles meticulously walking across every single floorboard within the castle. It ensures that every single line of code within the program is executed at least once during testing.
  • Decision Coverage: Taking things a step further, decision coverage is like exploring every hallway and doorway, ensuring you’ve taken both the left and right turns at every intersection. It guarantees that each decision point within the program (such as if statements and loops) is evaluated with both possible outcomes – true and false.
  • Condition Coverage: This is the most rigorous level, akin to meticulously checking every wall and secret passage within the castle. It ensures that each individual condition within a decision (e.g., the expression in an if statement) is evaluated to be both true and false at least once.

The Path to High-Quality Software

By incorporating path testing into the software development lifecycle, developers gain a valuable tool for creating exceptional applications. This structured approach ensures comprehensive coverage of potential execution paths, leading to the identification and rectification of errors before they manifest as real-world problems.

Inspired by: Path Testing: The Coverage

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

Equivalence Partitioning and Boundary Value Analysis – Effective Techniques for Test Case Design

This week,I am revisiting some fundamental test case design techniques: equivalence partitioning and boundary value analysis. While these terms might sound complex, they offer a structured and efficient approach to software testing, particularly for numerical inputs or situations with defined input ranges.

Equivalence Partitioning: Dividing the Input Landscape Strategically

Imagine a program that validates user age for login purposes. Traditionally, one might be tempted to test every single possible age value from 0 to 120 (or whatever the defined limit may be). This brute-force approach, however, quickly becomes impractical and inefficient as the number of possible inputs grows. Equivalence partitioning offers a more strategic solution.

Equivalence partitioning involves dividing the entire set of possible input values (the input domain) into distinct classes where the program is expected to behave similarly for all values within a class. These classes are called equivalence partitions. In the age validation example, we could define the following equivalence partitions:

  • Valid Ages: This partition encompasses all ages that fall within the expected range for a user (e.g., 0 to 120).
  • Invalid Ages: This partition includes all values outside the valid range, such as negative numbers or values exceeding the limit (e.g., negative numbers or ages greater than 120).
  • Empty or Null Values: This partition considers scenarios where the user leaves the age field blank or enters an invalid value that evaluates to null.

By identifying these partitions, we can significantly reduce the number of test cases needed for comprehensive testing. Instead of testing every single age within the valid range, we can select representative test cases from each partition. For example, we could test valid ages with values at the beginning, middle, and end of the range (e.g., 0, 30, and 120). Similarly, we could test invalid ages with a negative number and a value exceeding the limit.

Boundary Value Analysis: Sharpening Our Focus on Critical Areas

Equivalence partitioning provides a solid foundation for test case design. However, it’s important to pay close attention to the boundaries or edges of each partition. This is where boundary value analysis comes into play. Boundary value analysis focuses on testing the specific values that lie at the borders of each equivalence partition. This includes:

  • Minimum and Maximum Valid Values: In the age validation example, this would involve testing the program’s behavior with values at the beginning (0) and end (120) of the valid age range.
  • Values Just Above and Below the Valid Range: This involves testing one value above the maximum valid age (e.g., 121) and one value below the minimum valid age (e.g., -1).

The rationale behind testing these boundary values is that programs are often more susceptible to errors at the edges of their input domains. By testing these specific values, we can identify potential issues that might be missed by random testing within the valid range.

Conclusion

Equivalence partitioning and boundary value analysis are valuable tools for software testers. They promote efficient test case design, improve test coverage, and ultimately contribute to the development of high-quality software.

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

Summary of Testing

Hello everyone,

This is the last blog of this semester, so I want to share the knowledge and experience I have learned this semester, as well as my expectations and opinions on testing work.

I have learned a lot from having little knowledge of this test at the beginning to now having a basic introduction. Start by understanding the meaning of testing. Testing is not a job that only requires reverse disassembly of the code to ensure that it runs. It is very complex and requires you to use tight logical thinking to challenge the code from all aspects. For example, it is not only based on the input designed by the code, but also based on all forms of input to test whether the code will run or crash. And I also learned about equivalence class testing, such as what Normal/Robust and Weak/Strong testing are. These are very interesting and they have opened a door for me into the field of testing.

They also got me interested in testing jobs, and I’m now starting to pay attention to jobs related to game testing and code testing. I still have a positive view on the future of this type of work. Testing teams are very important to both businesses and customers. He ensured unnecessary losses and savings.

Moreover, in the assignments and activities this semester, I also learned how to use effective testing tools to help us conduct testing work more efficiently. With the help of tools, we can save a lot of working time and let AI and tools do low-efficiency work, while we can concentrate on high-efficiency work.

Anyway, the knowledge I learned this semester will be of great help to my future and work. I hope everyone who reads this blog can try to understand and learn software testing. I hope it will be helpful to you.

From the blog CS@Worcester – Ty-Blog by Tianyuan Wang and used with permission of the author. All other rights reserved by the author.

Understanding Object-Oriented Testing

In the realm of software development, testing plays a crucial role in ensuring the reliability, functionality, and quality of the final product. As software systems become increasingly complex, traditional testing methods may not suffice, particularly in object-oriented (OO) programming environments. This blog explores the intricacies of OO testing and its significance in software engineering practices.

Summary of Object-Oriented Testing

Object-oriented testing focuses on validating the interactions, behaviors, and integrity of objects, classes, and their relationships within an OO system. Unlike traditional testing methods that primarily test individual functions, OO testing addresses the unique challenges posed by OO programming, such as data dependencies, inheritance, polymorphism, and dynamic binding.

The blog outlines various techniques used in OO testing, including:

  • Fault-based testing: Identifying faults in the design or code and creating test cases to uncover errors.
  • Class testing based on method testing: Testing each method of a class to ensure its functionality.
  • Random testing: Developing random test sequences to mimic real-world scenarios.
  • Partition testing: Categorizing inputs and outputs to test them thoroughly.
  • Scenario-based testing: Stimulating user actions to test interaction patterns.

Moreover, the blog highlights the purposes of OO testing, such as validating object interactions, identifying design errors, assessing code reusability, handling exceptions, and maintaining system uniformity.

Purpose of Object Oriented Testing

  1. Object Interaction Validation: Ensure that objects interact appropriately with each other in various situations.
  2. Determining Design Errors: Identify limitations and faults in the object-oriented design, focusing on inheritance, polymorphism, encapsulation, and other OOP concepts.
  3. Finding Integration Problems: Evaluate an object’s ability to integrate and communicate within larger components or subsystems, locating issues such as improper method calls or data exchange problems.
  4. Assessment of Reusable Code: Evaluate the reusability of object-oriented code, ensuring that reusable parts perform as intended in different scenarios, leveraging features like inheritance and composition.
  5. Verification of Handling Exceptions: Confirm that objects respond correctly to error circumstances and exceptions, ensuring the software is resilient and durable.
  6. Verification of Uniformity: Maintain consistency within and between objects and the overall object-oriented system, enhancing maintainability and readability by following naming standards, coding styles, and design patterns.

Personal Reflection

While traditional software testing emphasizes system-level functionality and performance, object-oriented testing focuses on validating interactions and behaviors within OO systems. Both resources underscored the importance of rigorous testing in software engineering, albeit with different approaches.

In my future practice, I intend to incorporate elements from both traditional and object-oriented testing methodologies. By applying fault-based testing, random testing, and scenario-based testing techniques from OO testing, I aim to identify and rectify potential errors early in the development process. Additionally, I will continue to emphasize comprehensive system testing to ensure software meets user requirements and quality standards.

Understanding both traditional and object-oriented testing methodologies equips me to contribute effectively to the creation of high-quality software solutions. By integrating the insights gained from both resources, I am confident in my ability to enhance software testing practices and deliver reliable software products in today’s dynamic software development landscape.

Source: https://www.geeksforgeeks.org/object-oriented-testing-in-software-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.