Category Archives: Week 9

Decision Tables from a Template

Over the past few weeks in CS443 – Software Quality Assurance and Testing, we’ve been learning how to apply our boundary test classes to create Decision Tables and apply somewhat similar logic to create Program and DD-Path Graphs for code segments. Decision tables are visual tools used in software testing and analysis to specify actions based on given conditions. The strategy we learned in class of assessing all possibilities then systematically combining them based on the decision outcomes and particularly “Don’t care” scenarios seems like a useful and interesting way to map out test designs.

So, I decided to look into blogs discussing Decision Tables and their implementation in software testing and found a great post on ShiftAsia with abstract and specific examples alongside general discussion. This post is also quite recent – posted on January 9, 2024 – which is something I always appreciate as the software/tech world is constantly changing. It opens by describing how to create a Decision Table by representing it with the following matrix:

Condition Stub Condition Entries
Action Stub Action Entries

Condition stub: List of all conditions in consideration

Condition entries: Filled out with Y/N (or X) to cover all possible combinations of conditions

Action stub: List of all possible actions/output

Action Entries: Marked (generally with X or blank) to show outcome and an association between a condition and result.

This is then illustrated with an example of being able to register according to conditions of having a valid email, registered email, and valid password. I found this template and example helpful to better understand Decision Tables in general by comparing them to the steps we did in our In-Class Assignment 7. And, using the example of an altogether invalid email forcing all results to be “Invalid” makes sense logically for the column consolidation.

The process of combining columns and simplifying Decision Tables is reminiscent of CS254 – Computer Architecture and Organization concepts, particularly using K-Maps to calculate Sum of Products and Product of Sums. Based on similar responses to a variety of inputs, we are able to essentially combine and simplify the K-Map table and in turn the expression it produces. While K-Map logic works based on binary math laws rather than actual outcomes, there’s a clear correlation here as we represent outcomes with boolean values that can be easily represented in binary – as either a 0(false) or 1(true). My personal experience in CS254 wasn’t the best – I didn’t totally understand how many of the concept we learned are applicable in practical situations, so it’s cool and exciting to see it applied in software testing – an area I would’ve probably least expected it.

Sources:

https://blog.shiftasia.com/use-decision-table-in-software-development

From the blog CS@Worcester – Tech. Worth Talking About by jelbirt and used with permission of the author. All other rights reserved by the author.

Navigating the Nuances of Mock Testing: A Reflection

In the realm of software engineering, particularly within the course content of CS-401, the concept of mock testing stands out as a pivotal technique in the landscape of software testing methodologies. Recently, I delved into an insightful resource on mock testing https://www.geeksforgeeks.org/software-testing-mock-testing/ , which offered a comprehensive exploration of its applications, benefits, and best practices.

Why This Resource?

Choosing this article stemmed from my quest to understand the intricacies of unit testing, especially how mock objects can simulate the behavior of real dependencies. The clarity and depth of the article provided a solid foundation, aligning perfectly with our coursework on advanced software development practices.

Insights Gained

The article elucidates mock testing as a technique where simulated objects, or “mocks,” replace system dependencies. This isolation allows for the rigorous testing of individual components without the overhead or unpredictability of their real counterparts. Notably, the piece highlighted the distinction between mocks, stubs, and fakes, demystifying their respective roles in a testing environment.

Personal Reflection

Engaging with the material, I was struck by the elegance of mock testing in decoupling code, facilitating a cleaner, more modular design. The practice of defining expectations for mock objects not only enforces a contract between different parts of a system but also embeds a level of documentation within the test itself. Reflecting on past projects, I recognize instances where a lack of isolation complicated both the development and testing phases. Moving forward, I’m keen to apply mock testing more judiciously, ensuring each component can be tested in isolation, thus enhancing test reliability and code quality.

Applying What Was Learned from this Resource

In future software projects, I plan to leverage mock testing to streamline the development process. By isolating external dependencies and focusing on the behavior of the system under test, I anticipate a more efficient debugging and validation process. Furthermore, the insights gained on best practices will be instrumental in avoiding common pitfalls, such as over-mocking, which can obscure the clarity and purpose of tests.

Conclusion

The exploration of mock testing through [Resource Title] has been both enlightening and validating, reinforcing the relevance of mock testing within our CS-401 curriculum. As the software complexity grows, so does the necessity for sophisticated testing methodologies. Mock testing, with its promise of isolation and focused validation, is a technique I look forward to mastering and applying in my journey as a software developer.

From the blog CS@Worcester – Abe's Programming Blog by Abraham Passmore and used with permission of the author. All other rights reserved by the author.

Finding Your Path with “Craft over Art”: A Balance of Purpose and Passion

Summary of the Pattern:
“Craft over Art” is a pattern that addresses the tension between pursuing personal artistic aspirations and delivering work that serves a practical, often communal purpose. It suggests that while software development allows for creativity and self-expression, the primary goal should be to craft solutions that meet the needs of users, clients, or the community. This pattern encourages developers to find a balance between their artistic ambitions and the craftsmanship required to build reliable, usable, and maintainable software.

My Reaction:
The “Craft over Art” pattern deeply resonated with me. It articulates a dilemma I’ve often encountered: the desire to innovate and create freely versus the responsibility to deliver functional, user-centric solutions. This pattern has helped me appreciate the beauty and satisfaction that come from craftsmanship – the meticulous attention to detail and the joy of solving real-world problems. It underscores the importance of empathy and utility in our work, which I find both humbling and motivating.

Insights and Changes in Perspective:
Reflecting on this pattern prompted me to reevaluate how I approach my projects. I’ve started to see my work not just as a platform for personal expression but as an opportunity to impact others positively. This shift in perspective has made me more conscious of the users’ needs and the broader implications of my work. It’s a reminder that at the heart of technology lies the potential to improve lives, and this purpose should guide our creative and technical decisions.

Disagreements and Critiques:
While I agree with the core message of “Craft over Art,” I believe there’s room for a nuanced view that doesn’t see art and craft as opposing forces but as complementary aspects of creative work. The best solutions often come from a fusion of innovative thinking (art) and practical application (craft). Encouraging a dialogue between these aspects can lead to more holistic and innovative outcomes. Hence, while the pattern is valuable, it’s important not to diminish the role of artistic creativity in problem-solving.

Conclusion:
“Craft over Art” has offered me a fresh lens through which to view my role as a developer. It has emphasized the importance of balancing personal creative aspirations with the responsibility to deliver practical, effective solutions. As I continue my journey in software development, I am inspired to embrace this balance, ensuring that my work not only satisfies a technical or aesthetic urge but also serves a greater purpose. This pattern is a powerful reminder of the impact our choices as developers can have on the world around us.

From the blog CS@Worcester – Abe's Programming Blog by Abraham Passmore and used with permission of the author. All other rights reserved by the author.

Understanding Object-Orientated Testing

Testing In context of software development is a critical process that involves systematically checking a program or system to ensure it performs as intended. In software development, It is really important to check our work making sure everything works as it should. When we write code using object-orientated programming (OOP) which is a common way to organize and write our software, we need a special kind of checking called Object-Orientated Testing (OOT). This blog dives into what OOT is, inspired by the detailed article from GeeksforGeeks , showing why it is different and important.
Summary of the resource

The article from GeeksforGeeks explains how testing for Object-Orientated programming is different than traditional testing. OOP deals with concepts like classes and objects (which are basically groups of functions and data that model real-world things). OOT then focuses on checking these classes and objects, along with how they interact with each other, which is not something you do in traditional testing. The article talks about the challenges of doing OOT, like making sure objects work well together and the need for different tools and strategies to do it right.

Reason for selection

I picked this article because it does a great job of showing how checking object-orientated code is different from the usual way of testing code. It fits well with what we are learning in class about how to build software, giving us a clear picture of how to make sure out OOP projects work well

Reflection:

Reading about OOT made me realize that checking our code in OOP needs more than just looking at each part by itself. We need to see how all parts work together. It was an eye-opener to learn about the different tools we can use for OOT and how it helps us find and fix problems early on.

Looking forward

This article made me more aware of how important it is to use OOT in my future projects. Knowing how to do this kinds of testing means I can make sure my software is solid and works well, which is very important for any software developer.

Conclusion

Object-Orientated Testing is a key skill for software developers, especially as we build more complex and interconnected software. The insights from the GeeksforGeeks article highlights the unique aspect of OOT and remind us why adapting our testing to match our coding style is crucial. As we tackle bigger projects keeping these OOT principles in mind will help us build better and more reliable software

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

Week 9: CS-443

Static vs Dynamic Testing

Testing software and ensuring it works as intended is a crucial part of software development. Two approaches to testing are static and dynamic. Static testing involves testing the software without running the code, while dynamic executes the program and tests its behavior in various situations.

Static Testing

The term static testing comes from examining the code in a “static” state rather than actually running it. Because the code is never actually executed with static testing, the focus of testing is on analyzing the software’s documentation along with the design of the code, and the code itself. Static testing is most beneficial in the early stages of development. Since the code is never being executed, a fully working implementation is not required unlike dynamic testing. Issues identified early in development are easier and less costly to fix resulting in better maintainability, and decreased time and money spent in the long term. Some static testing techniques include informal reviews, walkthroughs, static code reviews, and more.

Dynamic Testing

Dynamic testing involves actually executing the software and testing its behavior based on various inputs. Test cases are created to conduct test runs to identify defects and ensure the software meets the required specifications. Along with testing the software with various inputs and comparing to the expected outputs, error conditions are also tested. Error conditions are inputs that are outside of the valid input range, and the software should be able to handle the invalid input without any unexpected behavior. Dynamic testing is performed after coding and development are complete, whereas static testing usually begins in the early stages of development. Because dynamic testing executes the code, the software must be far enough in development where the software functions, performs, and secure as intended. Those reasons are why dynamic testing is to be completed after development. Some dynamic testing techniques include unit testing, integration testing, and system testing.

Conclusion

This article was chosen because it clearly explained what static and dynamic testing are and the differences between them. The article was also easy to follow along. I enjoyed learning about when static and dynamic testing are most beneficial because I was unaware that static testing begins in the earlier stages of development while dynamic is performed after development. So far in my software development journey, I have not written many tests for the code I have written, and have mainly done manual testing which takes extra time and may have errors. Gaining insight in these techniques will be helpful when testing code in the future.

Resource:

https://www.guru99.com/static-dynamic-testing.html

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 using mocking and stubbing

In the world of software development, ensuring that your application works as intended is crucial. This is where testing comes into play, serving as a safeguard against unexpected behavior and bugs. But how do you test effectively? This is where concepts like mocking, stubbing, and contract testing become vital. Let’s dive into these techniques and see how they can enhance your testing strategy.

  • The Essence of Mocking and Stubbing

Mocking and stubbing are techniques used primarily in unit and component tests, but their usefulness extends beyond these. They are about creating fake versions of external or internal services to streamline and stabilize testing processes.

Mocking refers to creating a faux version of an external or internal service to replace the real one during testing. This is especially useful when your code interacts with object properties rather than behaviors. By mocking dependencies, you enable your tests to run more quickly and reliably since they are not bogged down by real-time data fetching or complex logic processing.

On the other hand, stubbing involves creating a stand-in for certain behaviors of an object rather than the entire object. This technique is useful when your implementation interacts only with specific behaviors of an object, enabling faster and more focused tests.

  • Practical Applications

When your code uses external dependencies, such as system calls or database access, mocking or stubbing comes in handy. For example, instead of actually creating or deleting a file during a test, you can mock or stub the file system’s responses. This not only speeds up the testing process but also ensures that your tests remain independent and easy to manage.

  • Contract Testing in Microservices

In a micro-services architecture, services interact based on predefined “contracts” detailing expected requests and responses. Contract testing verifies that these interactions meet the agreed-upon standards. Unlike traditional integration testing, contract testing focuses on the interfaces between services, making it a leaner and more targeted approach.

This type of testing is beneficial for checking the integrity and reliability of service interactions without deploying an entire system. It’s particularly effective in continuous integration pipelines, as it ensures that changes in one service don’t break the contract with another.

  • The Role of Mocks and Stubs

In contract testing, mocks and stubs play a crucial role. By simulating the services that an application interacts with, developers can check the consistency and reliability of the application’s responses without relying on live services. This approach significantly reduces testing time and increases reliability.

  • Conclusion

Testing is an integral part of the software development lifecycle, and techniques like mocking, stubbing, and contract testing are essential tools in a developer’s arsenal. By understanding and implementing these strategies, we can ensure that your tests are both efficient and effective, leading to more reliable and maintainable software.

The link to the initial blog post: https://circleci.com/blog/how-to-test-software-part-i-mocking-stubbing-and-contract-testing/

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

Understanding Mock Objects


Understanding Mock Objects: A Journey from Confusion to Clarity

When I first stumbled upon the concept of “mock objects,” it was during my foray into the Extreme Programming (XP) community. The term has since become more prevalent, particularly among those versed in XP-influenced testing literature. Yet, mock objects are frequently misconstrued, often mixed up with stubs, which serve as basic aids in testing environments. This confusion is understandable;

Mock objects represent a nuanced divergence in the realm of software testing, embodying both a shift in test result verification—state versus behavior verification—and an ideological split in testing and design methodology: classical versus mockist Test Driven Development (TDD).

Diving into Testing Styles

To elucidate, let’s consider a straightforward example: testing an order system interacting with a warehouse. In traditional state verification tests, we’re primarily concerned with the end-state of the system under test (SUT) and its collaborators after the exercise phase. Here, both the SUT (Order) and a real collaborator (Warehouse) are employed, focusing on the system’s final state to verify test success.

Conversely, tests utilizing mock objects—like those in the jMock library—adopt behavior verification, emphasizing the interactions between the SUT and its collaborators. Instead of a real warehouse, a mock warehouse is used, setting expectations for how the SUT should behave. This approach focuses not on the final state but on ensuring the SUT makes the correct calls to its collaborators.

Exploring Classical vs. Mockist TDD

The distinction doesn’t stop at test execution. It extends into the philosophy behind the testing approach. Classical TDD practitioners utilize real objects where feasible, employing stubs or mocks primarily for cumbersome collaborators.

Mock objects are born from the XP community’s focus on TDD, where design evolves through test iterations. This “need-driven development,” particularly championed by mockists, advocates for outside-in programming, starting from the topmost user interface layer and working inwards, designing the system piece by piece.

Fixture Setup and Test Isolation

Fixture setup and test isolation further differentiate the two approaches. Classic TDD often involves extensive fixture setup, creating the SUT along with all necessary real collaborators. Mockist TDD, by contrast, requires only the SUT and its direct mock collaborators, potentially simplifying test setup

Design Implications and Personal Reflections

The decision between classic and mockist TDD extends beyond mere testing strategy; it influences design philosophy and system architecture. Mockist TDD tends to encourage more decoupled, modular designs, as each component’s interactions are explicitly defined and isolated.

As someone who initially grappled with understanding mock objects, I’ve come to appreciate their value in elucidating system behaviors and fostering thoughtful design. Yet, the choice between classical and mockist TDD ultimately depends on individual project needs, team preferences, and the specific challenges at hand.By understanding the nuances between these approaches, developers can make informed decisions that best suit their projects, fostering environments where quality software can thrive.

Based link: https://martinfowler.com/articles/mocksArentStubs.html

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

CS343 – Week 9

Front-end development is focused on the user experience with the site. They design the elements of the application that the user interacts with and ensures that the interface is fast and easy to use. As technology continues to grow with different devices with varying screen sizes, a challenge that has arisen for front-end development is the accommodation for the different screen sizes that want to access the same site or application. There are different programming languages for front-end development, including HTML, CSS, and JavaScript. HTML (HyperText Markup Language) allows browsers to display text or load elements, rendering webpages for users. CSS (Cascading Style Sheets) is the standard language to identify how HTML content will be displayed, such as fonts, foreground and background colors. JavaScript (JS) extends the functionality of websites beyond HTML and CSS. This gives websites the ability to refresh themselves dynamically and respond to user actions without page reloads. You can also model UI components like pop-ups and interactive sliders.

While the front-end interface draws a lot of attention to the general audience due to the visual interaction with it, the back-end forms the backbone of any online program. It includes the logic, data storage, and security features required to create a fully functional and reliable application. It is also responsible for processing client requests, interacting with databases, and generating responses to be delivered back to the client. There are several different responses that can be generated depending on the quality of the request. Examples of some responses include 200, 201, 400, 404, and 500. 200 OK indicates the request was successful and returns the requested data. 201 Created indicates another successful request but creates a new resource rather than displaying an existing one. 400 Bad Request indicates the server could not understand the request due to malformed syntax. 404 Not Found is a different type of client error response which indicates the requested resource could not be found. 500 Internal Server Error indicates the server encountered an unexpected condition which prevented a successful request.

The use of databases is important when it comes to designing the back end for several reasons. Data persistence is a positive outcome from databases and ensures that information is not lost when an application is closed or is restarting. It also allows for better data management and efficient mechanisms for inserting, updating, deleting, and retrieving information. Concurrency control is allowed through the use of databases, meaning multiple users or applications can access and modify data simultaneously.

Front-End Development: The Complete Guide (cloudinary.com)

Back-End Web Architecture | AppMaster

From the blog CS@Worcester – Jason Lee Computer Science Blog by jlee3811 and used with permission of the author. All other rights reserved by the author.

Open Source Software in Education

     In recent times I have started a job as a computer teacher for a private school, and as such I have had to become familiar with a variety of educational software. As an educator, it is important for there to be a plethora of accessible software to teach children digital literacy, as computers have become increasingly incorporated into more facets of modern society Open-source software is one avenue that allows young students access to important tools to learn and create, without incurring a hefty price tag for their school. This is especially true for those learning how to code since it is not exactly a subject that comes naturally to everyone. While there are certainly many free IDEs out there for any aspiring adult programmer to use, I am more concerned with young children who may not be able to understand all the complex operations of standard IDEs. The best answer I have found is the educational coding software Scratch, created by MIT. Licensed under the “Creative Commons Share Alike” license, Scratch provides a drag and drop block-based coding environment that is easily understood and accessible to children. This allows teachers to easily demonstrate basic coding concepts like if-then-else statements and assigning variables. There’s even Scratch jr., available on tablets, that has an even more simplistic UI designed for even younger audiences. MIT has also released App Inventor, a free open-source software for creating mobile applications. These coding applications highlight the ability of open-source software to easily adapt to changes in social needs. But educational software does not just encompass programming and mobile apps, it also extends to various tools needed for academic success. Software such as ONLYOFFICE and LibreOffice, which provides a free alternative to Microsoft Office, is appreciated by students who cannot afford the more popular and expensive version. Not only are these applications useful within the U.S. education system, but another benefit they provide is their international reach. Since they are online and free for anyone to download and copy, they can be distributed to anyone globally with an internet connection. This opens new avenues for providing education to those in need. Education is a sector in need of accessible tools so that we can better teach the next generation and expand access to reliable education within our own borders and beyond. Not only that, but in this modern time where the importance of digital literacy is at an all-time high, we need to start laying the groundwork for future developers. 

https://scratch.mit.edu/faq

https://elearningindustry.com/open-source-tools-to-boost-digital-learning

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

application architecture, serverless

In CS-343, we’ve gone over three major architectures for designing applications. These three are the monolith, client-server and microservices architectures. Each has its strengths and weaknesses, but it seems as though if you can go with microservices, you should go with it as it provides stronger scalability and reliability even if it is much more complex.

From this, it seems like you would use the other architectures if you cannot afford to build a microservices architecture currently, do not have the time to do it, or if your team does not have the required skills / manpower to build up the architecture. It makes sense in the case where the application doesn’t need to be complex, but as time progresses, perhaps it will be that complex in the future, and having built from a monolith architecture ends up being a nuisance.

Out of curiosity, I wanted to learn about some additional types of architectures. I found this blog post written by Paul Gillin, and what stuck out to me was the serverless architecture model. His explanation of it is that it is an evolution of the microservices architecture, with the main departure being that it is, well, serverless. Services are run from software containers as opposed to being pulled from a server.

This idea interests me, not just because of not needing to construct a server with it, but also because it utilizes containers in a very effective way. In this course, I was interested in the practical uses of containers outside of simplifying development within a team, and it seems like this implementation is what I was looking for. Of course, there are some cases where a serverless architecture wouldn’t work, and this architecture is mostly suited for experienced teams due to its complexity, but it’s an interesting idea nonetheless.

After looking at other websites, I must mention that there is a distinction between a pure serverless architecture and one that utilizes containers. This webpage on the serverless architecture from DataDog makes this clear in the “Serverless Architecture vs. Container Architecture” section. Essentially, with a pure serverless architecture the cloud provider (AWS, for example) manages their servers, which means that you don’t have to manage it, but you do have to work with what they give you. With a container architecture, you have to update and maintain your containers, system settings, and dependencies for everything to work properly in place of a server.

With this distinction in mind, I definitely wouldn’t want to rely on an external cloud service, and so a container-based architecture does seem more appealing. Ultimately, though, every tool (and architecture in this case) has its uses, so it’s important to know and understand many architectures so you know what to use when you need to use it.

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