Author Archives: cameronbaron

Real-World Testing

This week, I read a blog post called “Netflix App Testing at Scale” which is based on an interview with Ken Yee, a Senior Engineer at Netflix. It takes a look at how Netflix tests their Android app, which is one of the most widely used streaming apps in the world. With over a million lines of code, 400+ modules, and support for all kinds of devices (including foldables and Android Go phones), testing at Netflix isn’t just about making sure the app works—it’s about making sure it works everywhere. I chose this article because we’ve been covering testing frameworks and strategies in class, and this felt like the real-world version of everything we’ve been learning. I also use Netflix a lot,  it is interesting to learn how they keep it running smoothly through so many updates and features. This blog helped me connect the theory from class to an actual large-scale product.

Netflix used to have a separate team of SDETs (Software Development Engineers in Test), but now every feature team handles their own testing. That includes unit tests, screenshot tests, and end-to-end tests. They still have two SDETs who help across teams, but quality is everyone’s job now. I thought that was cool—it encourages developers to think about testing earlier and more often, rather than just tossing it over to QA at the end. They also go into the frameworks they use. For unit tests, they use tools like Strikt (for fluent assertions), Turbine (to help with Kotlin Flows), and Mockito (for mocks). They also use Hilt for dependency injection and Robolectric when they need to test Android-specific logic. What stood out to me was how conscious they are of performance—each layer of test framework (plain unit → Hilt → Robolectric → device tests) adds more time, so they encourage developers to keep tests as fast and simple as possible. That’s a great tip I’ll definitely remember for my own projects. I also learned a lot from their section on flakiness. I hadn’t realized how much those little issues could mess up tests—and how fixing them makes everything more reliable. Finally, Netflix uses screenshot testing heavily. They use Paparazzi for Jetpack Compose UI, localization testing for checking designs across different languages, and even visual accessibility checks. It is interesting to find out that they care about accessibility and localization.

This blog gave me a better understanding of how layered and thoughtful good testing needs to be—especially at scale. I’ll definitely use what I learned about speed, flakiness, and strategy in my future development work.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

New Perspectives: Chris James’ TDD Thinking Hats

In our Software Quality Assurance and Testing course, we have been learning about Test-Driven Development (TDD) and how it supports building stable, maintainable software. Chris James’ blog post, “The TDD Thinking Hats,” connects directly to our coursework by offering a helpful way to think about the different stages of test-driven development. Instead of just following steps, James introduces the idea of “thinking hats” to better focus on what kind of mindset is needed at each point in the process. James also acknowledges the concept he is applying to test-driven development in this post stems from the “Six Thinking Hats” which is a broader idea that is from an Dr. Edward de Bono book.

James outlines three main hats:

  • The Green Hat is worn when writing a new test, emphasizing thinking like a user and focusing on desired behavior.
  • The Red Hat is worn when tests are failing, where the priority is to quickly fix the issue without making too many changes outside of the direct problem.
  • The Blue Hat is for the refactoring stage, when the tests are passing, allowing the developer to enhance the code

I chose this blog post because while test-driven development has been introduced in our coursework, I have sometimes found it difficult to manage the different phases clearly when applied. It is easy to get ahead of yourself — trying to refactor before a test passes, or worrying too much about details when writing a test. This concept helps me see how keeping a more distinct mindset at each step can prevent mistakes.

A point of interest for me was James noting that feeling uncomfortable during the Red stage is normal and even expected. In the past, when facing failing tests, I would often get discouraged or rush to fix the code without even thinking. Now I see that treating the Red stage as a signal to slow down and focus on getting back to green is a better approach. I also learned the importance of avoiding large changes while tests are failing, something I will pay closer attention to moving forward. Small incremental steps seems to be the recurring idea behind test-driven development

As I continue to learn, I plan to consciously apply this “thinking hats” approach when practicing test-driven development. I will aim to be more intentional: practical when writing tests, focused when resolving failures, and careful when refactoring. I expect that doing so will not only help me better follow the test driven development cycle, but also improve the quality and structure of my code overall. This blog post gave me a new practical framework to apply what we have been learning about test-driven development. It made the process feel more organized and achievable, which I believe will help me develop stronger habits for quality-focused software development.

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

Sprint Two Retrospective

This sprint pushed us out of the setup phase and into the real struggles of implemenation. Our focus was on certificate configuration, domain integration, and establishing a stable server environment capable of supporting frontend and backend communication through Docker Compose. We encountered technical challenges that required a lot of trial and error, especially with NGINX, RabbitMQ, and SSL certs, but we made real progress and learned a lot along the way.

Key Work Accomplished:
  • SSL Certificates: After experimenting with self-signed certs, we shifted direction and enabled Let’s Encrypt with Certbot. I verified auto-renewal functionality using a dry run, ensuring long-term reliability.
  • Domain & NGINX Setup: Switching from IP to domain access opened the door for proper HTTPS handling and better routing. We spent time researching NGINX as a reverse proxy and adjusted our configuration to support this change.
  • RabbitMQ Troubleshooting: I spent time debugging why connection.createChannel in messageBroker.js fails during Docker Compose builds. The issue appears tied to the container configuration or startup timing, which I plan to isolate in the next sprint.
  • Documentation: Added notes and resources for Docker Compose Watch (for future CI/CD use) and contributed to team documentation related to server setup and troubleshooting steps.

This sprint tested our patience and problem-solving skills. Even when progress felt slow, I stayed focused on learning and finding answers. I also made it a point to keep the energy positive in the team, especially when the same problem stretched across multiple weeks. I think maintaining that morale helped keep us all engaged and moving forward. One area I’d like to improve is how I manage my research time. It’s easy to get stuck digging through forums or chasing edge cases, so next sprint I want to be more intentional about how I explore solutions and when to pivot. I also want to get better at helping guide conversations to a technical conclusion more efficiently during group work. My top priority going forward will be testing subsystems and verifying proper communication across containers. I also want to finalize our server hosting and make sure the front end is accessible through the domain without errors. Overall, I’m proud of our persistence. This sprint was about learning and solving problems within the systems we’re building.

Apprenticeship Patterns: The Long Road

This sprint reinforced the mindset behind Apprenticeship Pattern: The Long Road—that true growth in software development comes from persistence, patience, and a long-term commitment to learning. While troubleshooting issues like Docker container problems and RabbitMQ errors was frustrating at times, I stayed focused on understanding the root causes. Each challenge became an opportunity to learn. I’ve started recognizing that even slow progress is part of the journey to achieving the goal. This pattern will help me stay motivated and positive, even when things don’t go as expected. Moving forward, I want to manage my time better when diving into technical problems and continue building habits that support my learning and my team. There is still a lot of work to complete for our team, but I think we expect this and we will hit the ground running for the last sprint.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

Comprehending Program Logic with Control Flow Graphs

This week I am discussing a blog post titled, “Control Flow Graph In Software Testing” by Medium user Amaralisa. When I read through this post initially, it immediately clicked for me with what we have been studying in class with different path testing types which capture the logic similarly. The comparison between CFGs and a map used to explore the world or get from point A to point B is incredibly useful as it explains the need for having a guide to explain the many execution paths of the program. The writer made the topic easy to understand while still including the technical information that is required to apply these techniques moving forward.

This post helped me see the bigger picture in terms of the flow of a program and how the logic is truly working behind the code we write. It tied directly into what we’ve covered about testing strategies, especially white-box testing, which focuses on knowing the internal logic of the code. The connection between the CFG and how it helps test different code paths felt like a practical application of what we’ve been reading about in our course.

It also made me think about how often bugs or unexpected behavior aren’t because the output is flat-out wrong, but because a certain path the code takes wasn’t anticipated. Seeing how a Control Flow Graph can lay out those paths visually gives me a better sense of how to test and even write code more deliberately. It’s one thing to read through lines of code and think you understand what’s going on, but when you actually map it out, you might catch paths or branches you hadn’t considered before. I could definitely see this helping with debugging too—like, instead of blindly poking around trying to find what’s breaking, I can trace through the flow and pinpoint where things start to fall apart.

I also really liked that the blog didn’t try to overcomplicate anything. It stuck to the fundamentals but still gave enough technical depth that I felt like I could walk away and try it on my own. It gave me the confidence to try using CFGs as a tool not just during testing but also during planning, especially for more complex logic where things can easily go off track.

Moving forward, I am going to spend time practicing using CFGs as a part of my development process to ensure that I am taking advantage of tools that are designed to help. Whether it’s for assignments, personal projects, or even during team collaboration, I think having this extra layer of structure will help catch mistakes early and improve the quality of the final product. It feels like one of those concepts that seems small at first, but it shifts the way you approach programming altogether when applied properly.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

Understanding FIRST Principles: Remastered

This week I am diving into an article by David Rodenas, PhD – a software engineer with a wide array of knowledge on the topic of Software Testing. I found the article, “Improve Your Testing #13: When F.I.R.S.T. Principles Aren’t Enough” which is one of many posts from Rodenas that helps provide insights to Software Testing that only a pro could provide. Through this article, Rodenas walks through each letter of the FIRST acronym with new meaning – not replacing what we know but instead enhancing what we know. As the author teaches us these new ways of understanding, examples are provided to look for ways in our own work in which these can be applied.

The acronym can be read as: Fast, Isolated, Repeatable, Self-Verifying, and Timely, but taking this one step further we can acknowledge the version that builds on top of this as: Focused, Integrated, Reliable, Significant, and Thoughtful. It is obvious that these definitions are not opposites of each other, they should also exist cohesively in our quest for trustworthy software.

One pro-tip that sticks out to me here is keeping your code focused by avoiding using the word “and” in the test name. When I first read it – it seemed kind of silly, but in a broad-sense it really does work. The writer relates this to the Single Responsibility Principle – by writing tests with a clear focus, our tests are fast and purposeful. Another takeaway is the importance of writing reliable and significant tests. Tests should not only validate but also provide meaningful information for what went wrong to cause them to fail. A test that passes all the time but fails to catch real-world issues is not significant. Similarly, flaky tests—ones that pass or fail inconsistently—break trust in the testing suite and should be avoided. Rodenas also emphasizes that integrating tests properly is just as important as isolating them. While unit tests should be isolated for precision, integration tests should ensure that components work together seamlessly. A good balance between both approaches strengthens the overall reliability of a software system.

Ultimately, this article challenges us to go beyond simply following FIRST principles and to think critically about our testing strategy. Are our tests truly adding value? Are they guiding us toward our goal of thoroughly tested software, or are they just passing checks in a pipeline? By embracing this enhanced approach to testing, we can ensure that our tests serve their true purpose: to build confidence in the software we deliver.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

Sprint One Retrospective

Retro

This first sprint was a deep dive into new territory. Our team focused on understanding our project, setting up the proper tools and environment, and managing challenges as they arose. We have created a working agreement, completed multiple issues on GitLab as individuals and as a team, and we have ensured collaboration was a priority throughout each task.

GitLab Activity:

  • README.md – Updated the README document for our GitLab group to detail the major goals of our project.
  • Docker Compose Watch Documentation – Drafted documentation for Docker Compose Watch for possible use for CI/CD later on

Our team dynamic has been great from the beginning with a strong working agreement in place from day one being we were able to focus on the work getting done without worrying about team cohesion. We were able to complete a lot of research during this sprint to gather information about Docker and its many variants, NGINX, and CI/CD options. This research was turned into details documentation within our GitLab group. We worked successfully toward solving problems like issues with debugging Docker Containers, using SSL certificates properly, and scheduling our tasks based on priority. Overall, flexibility in our team has been vital and we have adapted to any challenges that we have faced.

I believe we have already learned a lot through our research and time spent of digging around in the server for answers, but we can still work toward improving our outcome by approaching our research differently and ensuring we have a clear focus on what we want to accomplish. Personally, I plan to improve my work by improving my time management regarding troubleshooting/research because sometimes I can find myself down a rabbit hole and working to ensure that all of my teammates and I are on the same page through clear communications.

Apprenticeship Pattern: Retreat into Confidence

“Retreat into Competence” is a strategy for regaining confidence when feeling overwhelmed by complex challenges. It involves stepping back into an area of expertise before pushing forward again. The key is to avoid staying in the comfort zone for too long and instead use the retreat as a way to launch forward with renewed energy. During this sprint, there were moments of troubleshooting that felt a bit discouraging, particularly with Docker and SSL certificates, where progress seemed a little slow and confusing. The feeling of being stuck highlighted the need to step back into something familiar—whether it was revisiting basic Docker configurations or focusing on smaller, more manageable tasks like completing documentation on GitLab—before tackling the larger issues again. Had I known about this pattern sooner, I would have structured my work differently to maximize results. Moving forward, I plan to:

  • Time box troubleshooting sessions to avoid going down the rabbit hole
  • Focus in my research to ensure that the resulting information is useful to our project
  • Seek help from teammates during moments of need
  • Ensure that I am still completing the smaller tasks that can be completed while working on larger issues

This sprint was a valuable learning experience in both technical and team collaboration aspects. While challenges arose, the team adapted, and I gained insight into how to manage difficult situations more effectively. By refining research strategies, improving troubleshooting workflows, and applying patterns like “Retreat into Competence,” I can optimize future sprints for even greater success.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

Apprenticeship Patterns Intro

After reading through the assigned sections in the text Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman by Dave Hoover and Adewale Oshineye I feel as though I have already learned lessons that are vital to my progression as a computer science student. One lesson that stood out to me was the story of the Zen master, I really enjoyed the symbolism in the story and the alignment with real experience. In all aspects of life it is important to feel confident in one’s knowledge, but the other half of this is knowing when to be humble enough to learn and accept new information when it is presented. As many of us are familiar, the world of computer science is a realm of continuous improvement – this story helps to remind me how hard it would be to be successful in practice if I do not continue to save space for learning.

Another thought-provoking section was the introduction to Chapter Three relating to Daves realization of the extraordinarily long road of learning that lies in front of all of us. Though the passage was short it was notable to me because I remember having this realization myself. When I came to terms with the fact that there was (likely) no one that knows everything and that most of us are all on the same path just at different points along the way – then I was able to freely learn from my honest starting point, wherever that may be, in any given topic without the shame of being a newbie. Another thought I had while reading this section was that although certificates can be helpful and feel like an accomplishment they are only as valuable as you make them. Being able to use what was learned within a certificate course (or similar) and build upon that I think is where the majority of the real learning occurs.

Apprenticeship Patterns has really helped me rethink how I approach learning. The Zen master story reminded me that it’s important to stay humble and always be open to new ideas. I also liked the reminder that learning is a never-ending journey. These insights will definitely help me stay focused on growing and applying what I learn as I move forward in my studies.

From the blog cameronbaron.wordpress.com by cameronbaron and used with permission of the author. All other rights reserved by the author.

CS-443: Self-Introduction

Hi everyone, I am Cameron Baron – a senior Computer Science student at Worcester State University. This is an introductory post for my Software Quality Assurance and Testing course to ensure all blog posts will be posted as expected. Upcoming blog posts will be centered around finding useful information and various tutorial overviews related to this topic as I continue to learn.

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

Discovering LFP and Thea’s Pantry

The LibreFoodPantry (LFP) website and Thea’s Pantry GitLab Group are full of knowledge about the open-source project itself and related information to support the users and developers. After reading through these resources, I felt I gained a more thorough understanding of the purpose of this software and it’s potential trajectory. Specifically relating to the LFP website – I found the Values section extremely useful, as it provides clear expectations for all community members with links to further understand the Code of Conduct and to learn more about Agile values and FOSSisms. Regarding the information about Thea’s Pantry in GitLab, there are many useful subsections within this group, but I was particularly impressed by the Architecture section as it presents the microservices architecture clearly through diagrams with clear systems, features, and components. An additional useful link relating to Thea’s Pantry GitLab Group is User Stories. After reading through the different situations expressing the intended use of the software, I had a better understanding of the role that this project plays throughout every step of this process on both, the staff side and the guest side. I was surprised reading the User Story titled “A Pantry Administrator Requests a Monthly Report for the Worcester County Food Bank” as I was unaware of the link between the two systems. Overall, these webpages provide a simple and clear interface to learn about the project’s values and community expectations, as well as, technical details.

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

Reliability in Development Environments

This week, the blog that caught my attention was “How to Make Your Development Environment More Reliable” by Shlomi Ratsabbi and David Gang from the Lightricks Tech Blog. This work highlights common challenges encountered in software development and provides actionable solutions — specifically, how to optimize development environments. The insights offered in this blog align perfectly with our coursework, as we have continuously learned about and worked within our own development environments. This post emphasizes the importance of ensuring consistency and reliability when creating these environments, offering practical advice to achieve this goal.

The writers begin by outlining the necessity of development environments, describing the challenges that arise during software releases. These challenges include discrepancies between local and production configurations, mismatched data, permission conflicts, and system interaction issues. While creating a shared development environment may seem like the obvious solution, the authors point out that this approach introduces its own set of problems, such as debugging difficulties due to parallel testing, interruptions caused by developer collisions, and divergence between shared and production environments.

To address these challenges, the authors advocate for the implementation of branch environments. Branch environments are independent, isolated setups for developing and testing specific features or issues. These environments, when paired with tools like Terraform, Argo CD, and Helm, enable integration with Infrastructure as Code (IaC) and GitOps, automate infrastructure management, and ensure automatic cleanup of unused resources. This approach promotes consistent documentation of dependencies and application details within version control systems like GitHub. The blog includes a clear diagram and code snippets that effectively demonstrate how to set up branch environments using these tools, making it accessible and actionable for readers.

Branch environments offer several key advantages. By isolating changes, they ensure that all updates are properly tracked, simplifying debugging and maintaining consistency across development efforts. This isolation also eliminates conflicts inherent in shared environments, reducing the risk of outdated configurations or data interfering with new testing and development efforts. Tools like Terraform and Argo CD further enhance this process by automating repetitive tasks such as infrastructure provisioning and application deployment, saving developers time and reducing the likelihood of human error.

Additionally, branch environments improve resource efficiency. Since these environments are ephemeral, they are cleaned up automatically when no longer needed, freeing up valuable system resources and lowering costs. The inclusion of tools like Helm simplifies configuration management, even for complex architectures, ensuring a streamlined, manageable workflow.

Overall, this blog provides a thorough and practical framework for tackling one of the most common challenges in software development: creating reliable and consistent environments. The adoption of branch environments combined with IaC and GitOps principles enhances scalability, collaboration, and efficiency. As I continue to develop my own projects, I plan to incorporate these strategies and tools to build environments that are both robust and resource-efficient.

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