Author Archives: amoulton2

Legacy Tests : A Problem From Mindset

The blog post “What Do You Fix When You Fix a Test?” by Joep Schuurckes explores the nuanced decisions developers and testers face when a test fails. The central question is whether the issue lies in the test itself, the code under test, or possibly even the expectations behind the test. Schuurckes starts with bringing up the topic of legacy tests, legacy test code that makes “more decisions about what and how things are tested than the team.” He encourages readers to reflect before blindly “fixing” a test by editing it to pass again. This is what he calls “tests-as-code” where the developer is trying to change the code of the test so that it passes rather than treating it with the mindset of “tests-as-code”. “Tests-as-code” would be where the developer looks at a failing test as an information dump where each test returns some kind of data and thus any changes must preserve that data return. Part of keeping tests as code is keeping to a naming scheme so that each test is obvious in what you are expecting as a return which is the exact same thing I was taught in class, but now I understand the reasoning a bit more.

This post made me rethink what it means to “fix a test.” I’ve been guilty of tweaking test code just to get everything green in the test runner again, without stopping to think whether the test was telling me something important. Joep’s approach feels like a call for discipline and care in testing—treating tests as important resources in the codebase rather than disposable tools. The idea that tests should be maintained with this way of thinking resonated with me, especially since I’ve seen how neglected or misleading tests can erode trust in automated test suites.

Going forward, I want to adopt a more mindful approach when a test fails. Instead of rushing to “fix” it, I’ll start by asking why it failed. Is the requirement outdated? Is the test too brittle? Has the functionality truly changed? Also, I want to be more deliberate in writing tests—designing them to clearly document behavior and to be resilient against irrelevant changes. This is especially relevant for integration tests, which are often more vulnerable to external factors and instability. By treating each failed test as an opportunity to learn, not just a checklist item to resolve, I hope to contribute to codebases that are easier to maintain and trust.

source :
https://smallsheds.garden/blog/2024/what-do-you-fix-when-you-fix-a-test/

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Testers Aren’t Developers ! Their Role Is There for a Reason

The article “The Difference in Perspective of Testers and Developers” by Vijay provides a comparison of how software testers and developers approach software QA and testing. Developers are often focused on building features that work as intended, with an optimistic mindset geared toward implementation. Testers, on the other hand, adopt a critical mindset, aiming to uncover flaws, edge cases, and unintended consequences. The article explains that while developers ensure that the software does what it’s supposed to do, testers ensure it doesn’t do what it’s not supposed to do. This difference in thought processes is not a conflict but a complement to creating robust, reliable software. The article encourages improved collaboration, mutual respect, and open communication between these roles to produce higher-quality software.

Reading this article gave me a better understanding of how vital both roles are in the software development lifecycle. As a CS student who has done more programming than testing, I’ve often written code with the assumption that if it runs without errors and produces the expected result, it’s good to go. But throughout my QA and Testing class, through reading different blogs, I now see how much that perspective misses. I haven’t always taken the time to think about how a user might unintentionally (or maliciously) use the software, or how fragile assumptions can be unless they’re tested thoroughly. It’s easy to feel like bugs are personal flaws, but this article helped me appreciate the tester’s role and the stark difference in mindsets because I truly saw testing as just another tool in the developer toolkit and not as the fully fleshed-out role it is.

This new understanding is something I plan to apply in future group projects. I want to make a conscious effort to invite feedback from teammates who are testing my code, and more importantly, not take that feedback defensively. I also want to improve my own testing practices by thinking like a tester during development. That means writing unit tests that go beyond the “happy path” and trying to break my own code before someone else does. In larger projects, I now see the importance of collaboration between testers and developers early in the development process, rather than waiting until the end to start thinking about quality. Encouraging open communication can lead to better designs and fewer bugs downstream.

source:
https://www.softwaretestinghelp.com/the-difference-in-perspective-of-testers-and-developers/

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Making Code Stronger with JUnit 5

Blog Post: Making Code Stronger with JUnit 5

This week, I found a blog post called “Increasing Code Fortification: A Guide to Security Testing in JUnit 5”, and it gave me a new way of thinking about security in my code. I already knew JUnit 5 was useful for unit testing, but I hadn’t really thought about using it to test for security issues too.

The post talks about how developers can use regular unit tests to check for vulnerabilities early on, instead of waiting until the very end of development. It explains different strategies, like testing bad input, enforcing boundary checks, and even trying to break your own code to make it stronger. The idea of using parameterized tests to throw lots of different attacks at your code really stood out to me. I liked how the blog makes it so straight-forward.

Reading this made me realize I thought of testing as a question of”does it work?” — not “is it secure?” I like the idea of making security testing part of the normal coding routine, instead of something extra you only do if you have time. It’s a good reminder that security isn’t just about firewalls and encryption; it’s about the small choices you make in everyday code. The blog really emphasized that testing for edge cases and unexpected behavior can be just as important as making sure the “happy path” works.

One thing I found especially interesting was how JUnit 5 makes it easy to run the same test with multiple different inputs using parameterized tests. I had used this feature a little bit before for checking different types of valid inputs, but I hadn’t thought about using it to simulate attacks or unexpected bad inputs. For example, passing in SQL injection strings or unexpected data types could help catch vulnerabilities early before they become serious security problems.

I also liked how the blog encouraged starting small, not talking about designing a full-blown security test suite right away. Even adding a few security-focused tests for each feature you write can slowly build a stronger, more resilient application over time. It made me think about how easy it is to treat the idea of “security” as something separate from “normal” code and how easy it is to break it down into a couple tests per feature makes it much more manageable that coding the project and then trying to apply security testing.

In my future projects, especially ones involving databases, user input, or authentication, I want to make sure I’m thinking about security from the start. Testing with bad input and thinking like an attacker isn’t just for cybersecurity experts — it’s something every developer should get comfortable doing. Using JUnit 5 for this feels like a natural extension of skills I’m already using.

Overall, this blog post made security feel a lot more approachable. It gave me some simple ideas I can apply right away, and it motivated me to be a little more critical and thoughtful about the code I write, not just whether it works, but whether it’s strong enough to handle real-world problems.

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Sprint 2 Retrospective Blog Post

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based/backend/-/commit/c8faf74ca26ca4a71df0fb5fa09a428c0c473172
[fix: server persistence issue resolved] – The entrypoint that connected the server and the backend image terminated before the server could build itself.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based/backend/-/commit/162e710813fe4efd59ee9dfdf6d8bd387eabd864
[Merge branch ‘API’ into ‘main’] – Packaged my work on the API (endpoints, openapi.yaml, javascript classes, and database methods) and combined it with the main branch.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based/backend/-/commit/03ca867390a3541020e52b5bce95102002890fda
[chore: updated README.md] – Embedded hyperlink to reference repository and filled in some of the project details.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based/backend/-/commit/ddbc5ae04b174ec3d2bcf981b888726345c6d410
[fix(data):”data folder rename to inventory-data”] – The .gitignore was set to not track any folder titled data, the inventory.js object was in a folder called ‘data’ and as such I changed the folder name.

https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based/backend/-/commit/514777ff2ff6cd531bee0b480c3d946d7b6cba13
[Merge branch ‘inventory.js’ into ‘main’] – While the server would build correctly, the API was not pathing correctly and any calls would result in 500 errors, skipping the executing body of the endpoints and this was my fix.

Throughout this sprint our team as a whole was rather productive. We planned out some targets for the weeks and were constantly asking questions to the professor so that we understood the goalposts we could set for ourselves. I believe we learned a lot, I myself certainly learned a lot. For instance, in order for the frontend of our project ( https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem-category-based ) to use the backend I worked on we needed an image to be pulled from gitlab. The trick was that in order for gitlab to make the image of our backend it needed to pass the project’s pipeline, which we had not even begun to look at and turned out to be extremely labor-intensive. But we asked the professor when we had confusion which would generally set us back on the path and sometimes we just asked general questions on stuff we had not yet touched on so that we could tackle another piece of the project at a later date.

We were not always able to make it to meetings. At the beginning of this project we had made agreements to make it to all the class meetings and last sprint we added a Saturday call that begun at one. I know that I missed one of the Saturday meetings due to being sick but as a group I cannot recall a day where we all were in the call and that does sort of stick with me since at least once members of the group verbalized that they would be there and then not show up. In my opinion, it is crummy to be putting in the effort to have this meeting that everyone in the group agrees is the correct thing to do yet there are group members that are not participating just about every week.

I think a contract needs to be made, not a legally binding one mind you, that has input from every member of the team and is signed by every member of the team. To be clear, this is not something where it is forced upon each person to sign. If any one has an issue with a part that someone else offered then as a group we should come together and compromise on the issue so that everyone agrees to the provision. This is just a way I thought of to put a little more concrete understanding into the team dynamics.

As an individual I have not held up to my end of the agreement I made with the team. I said I would put forward updates to the group every week so that everyone understood my progress in my work and I utterly failed to follow through. I will simply have to keep this promise in mind for this next sprint.

Pattern : Use the Source
Summary : Seek out other people’s code and read it.
Reason for selection : Throughout this sprint I had Thea’s Pantry GuestInfo Backend open in my browser and I was constantly referring to it whenever I was confused about my codes errors.
How it would have changed me : In this case reading up on this pattern would not have changed my approach and in fact this is the reason I picked this pattern. I was already following through on this Apprenticeship pattern and reading it allowed me to put my methodology for this last sprint into words.

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Sprint 1 – Retrospective Blog Post

Evidence of Activity on GitLab

Reflection on What Worked Well

We planned some meetings outside of class, both of which went decently smooth. Our in class meetings were very productive and helped to set the goals for the week and keep expectations at a reasonable level. I believe that the way we split the work allowed me to focus wholly on my parts and succeed.

Reflection on What Didn’t Work Well

We didn’t end up tracking our work on this project correctly. There is work done that didn’t make it to the gitlab. Also there wasn’t a lot of using gitlab’s tools for tracking projects the way it was intended. Also some communication is getting lost between teammates.

Reflection on Improvements as a Team

I think the issues I addressed with gitlab are not too hard to fix, we just need to meet up and talk out our vision for the project. The communication issue is probably going to be harder as one group member has so many new ideas that sometimes the plan they have has changed from what was last discussed and that leads to some confusion.

Reflection on Improvements as an Individual

I personally have issues confronting people directly when it comes to ideas that I have issue with. For example, I have said before that our group should not make promises about features that aren’t explicitly in our project’s goal. I believe that the time for extra pieces that aren’t mission critical is after a viable product is finished. During a meeting with the client a teammate made a promise on a feature that wasn’t in the specifications originally. I had previously told this teammate this fact and that it was going to add more work to a project that we were already a bit behind on. Despite this communication happening, with no heads-up to the rest of the team this teammate promised to the customer that feature would be there. This upset me a bit but I can’t seem to find the courage to step up, say how I feel, and put my foot down on this issue.

Apprenticeship Pattern: Practice, Practice, Practice

Summary: If all the work you are doing requires 100% best work then find the time to practice on your own, in an environment you can make mistakes in.

Why I Selected This Pattern: I have rather high levels of anxiety when it comes to my work that others see. Instead of just the main branch being the stage where everything needs to be perfect, I saw everywhere I put any code to be a place requiring my maximum effort and best possible work.

How This Pattern Changed My Behavior: I read this chapter and because of it I made a personal repo and, from scratch, mirrored the work I was going to do in the team repo in that private repo first. It took me hours, but once I had a grasp of things I went into the team repo and it was much easier to crank out my work because I had a much more stable foundation to work from.

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Apprenticeship Patterns : Software Craftsmanship

The first chapter of the book Apprenticeship Patterns describes what the authors call The first chapter of the book Apprenticeship Patterns describes what the authors call “Software Craftsmanship”. While the general definition came from medieval times and relates to guilds and master/apprentice relationships, the definition used by the authors comes from a combination of these medieval principals and Peter McBreen. Peter’s definition starts from craftsmanship being opposite of the engineering and scientific approach to computer science. This view of craftsmanship being alternative to program, however the authors hold the opinion that both approaches are part of an ideal software dev landscape. I found this hard to wrap my head around the first go around but I hope that as I continue here readers may also get a better grasp of this “craftsmanship” mindset.

First is the manifesto. Each idea is taken from one of many other highly skilled people who were interviewed by the authors.

  1. Have a growth mindset – there is always a better solution and the only way to get there is to be prepared and work for it. Chiefly, this effort is what makes you smart and talented. I love this idea as it’s a brighter outlook on the world compared to the “talent is born and failure proves lack of talent” crowd.
  2. Accept that you will lack something and pursue the solution – this one is hard for me personally. I tend not to admit my lacking at first or second blush. However, once it is clear that I am ill-informed/confused/missing something I will search relentlessly until I find the proof I am wrong/the reason my thought process was flawed because going through life without a proper set of logic to solve problems will lead to a tough time. As such, I strongly agree with this tenet.
  3. Favor pragmatism over dogmatism – this is a doozy for me because I really love perfectionism. To be clear, this tenet is 100% true, no doubt in my mind. However, knowing that there exists a better way to do something is always hard to square with pragmatism. I know my code hits the necessary parameters, but it doesn’t do everything as efficiently as possible and that makes me want to tweak my code in so many ways.
  4. Favor sharing information over hoarding – I understand this idea and mostly agree to this ideal. I still think there is room for some level of hoarding in some cases, not everyone is a saint and some tools are definitely dangerous in the wrong scenarios.
  5. You must be willing to try and fail – I find this to be easy to follow, maybe because it ties in with a lack of knowledge on my part meaning most projects I work on are about techniques and knowledge I do not have.

I will continue posting more about this chapter later this week as there are a few more tenets to dissect and they are an interesting perusal. This first chapter is truly an interesting read and I hope these ideals don’t find themselves turned into corporate rule sets.

From the blog Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Intro to Software Quality Assurance & Testing

My name is Alex Moulton and this is my blog I use to talk about interesting happenings in computer science or interesting things I learn about.

From the blog CS@Worcester – Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

RESTful API: Tips and Tricks

REST stands for Representational State Transfer and API is application programing interface. Simply put, when there are multiple systems working together, a RESTful API allows a person to query or edit information in the system. I recently read a javaguides post on how to set up properly scalable API’s and wanted to share a short summary.

Tip 1: Domain Model-Driven Design
This means you should have the structure mirror the real-life pieces. So if, for example, you want the items of an order, the endpoint should look like “/orders/{id}/items”. Also, don’t nest it too deep, it will add needless complexity.

Tip 2: Choose HTTP methods appropriately
The 4 main methods and their use cases are; GET for getting data, POST for posting a new object to the database, PUT for putting a new object in place of an existing object, DELETE for deleting objects in the database. There is also PATCH which can be used patch an existing object. If you are using GET to modify an object you are adding unnecessary complexity. I personally will be adapting my use case of PUT after understanding the difference with PATCH

Tip 3: Implement Impotence Properly
A method is idempotent if no matter how many times it is called after the first, there is no behavior change from the first call. If you call DELETE multiple times on the same object then only that object should be deleted. GET is already idempotent, it will always get the object’s data regardless of whether you already called GET. PUT and PATCH should be implemented similarly to DELETE. The hiccup is with POST, because simultaneous calls are possible (two people can create new objects with the same identifier) logic to handle these calls needs to be made.

Tip 4: Chose the correct HTTP status calls
When a call is made, there are codes for the result. They are; 200 for a valid request, 201 for an object being created, 400 for an incorrectly formatted request, 401 if requester is unauthorized, 403 for a forbidden request, 404 if the object request is not found, and 500 for a server-side error. I am going to research more about how the permissions are set up when someone makes request and the logic behind blocking certain requests.

Tip 5: Versioning
Include which version of the API the request is using, maybe put it in the path “/v1/users”. They also list alternatives such as having a query parameter “/users?=v1” or adding a HEADER to the request that includes the version number. I never thought about adding versioning to the request but it makes sense to allow for previous versions to still request.

Tip 6: Use Semantic Paths
Singular resources use singular nouns and the path should be using the resources.
DON’T: POST /v1/loginUser
DO: POST /v1/users/login

Tip 7: Support Batch Processing
Something like:
POST /v1/users/batch
to allow for multiple users to be made in one POST.

Tip 8: Use query parameters for flexibility
You can add the ability to sort the data requested, or filter it, using queries. So:
/v1/users?age=gt:20
and
/v1/users?sort=name:asc
This is some awesome functionality and I cannot wait to implement it in my own system.

Link:
https://www.javaguides.net/2024/12/top-8-tips-for-restful-api-design.html

From the blog CS@Worcester – Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Agile: Continued

Quick recap of the first post, Miriam Posner saw an Agile team working and as an outsider decided to research more about the process. The article started with the defining of programmers as software engineers, an attempt to add structure to the confusing new field. From there was the “waterfall” development process, a term coined as a joke that was picked up by the management and used until the inflexible nature nature caused one too many projects headaches. A new movement was made by 17 managers who wrote the “Agile Manifesto” in February 2001.

Picking up from there Miriam goes into a little more detail on “waterfall” shortcomings as developers see it, the largest of which appears to be that any slowdown was seen as a ‘deviation from management’s careful plan’ because software development was inherently stable, at least from management’s pov. Agile was supposed to be about removing long-term, higher level plans set in stone in favor of short-term, quick-paced goals that would give more flexibility for developers. Remove useless meetings about every little thing so developers can actually fix the problems at hand. Miriam notes that at this time there were few qualified devs, so they had all the power and could have asked for unions or complete IP ownership. Instead they asked for more efficient working conditions so they could do their jobs.

While this sentiment from coders culminated in the 2001 manifesto, according to the Agile consultants Planview it took until 2012-2015 for more than 50% of active development teams to characterize themselves as “Agile”. So that was it right, new mindset and all’s hunky-dory. Except it wasn’t.

In a cruel twist of fate, Miriam noticed a flaw in that Agile team that she had been watching be so efficient and intriguing. They didn’t seem to be getting much work done. What had happened was that due to throwing out the top-down approach to project management, no one on the coder’s side had a solid concept of the project in its completed form. They had thrown out the baby with the bath water. Add on to the fact that, while definitely anti-management Agile was in a way very pro-corporate. The entire mindset was let developers put their all into the project, which in turn is believed to have contributed to the recently seen burnout rate increases. On top of this is the issue that, due to Agile’s inherently non-structured nature as a mindset, there’s no one thing someone can point to to say “this is not good we need to change it.” Since nothing is actually defined in Agile, everything is subjective and thus at the whim of whatever the company decides.

From this article I have come to see that flexibility in my future work is necessary, don’t try to plan every part from day one. However it is equally important to try to start with a skeleton, something that I can add my features to so that I know both where my projects are at as well as what it can become. Hopefully this adjusted mindset will allow me to continue doing what I love for a long, long time.

Link:
https://logicmag.io/clouds/agile-and-the-long-crisis-of-software/

From the blog CS@Worcester – Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.

Agile: What is it and why do some people not believe in it anymore?

This article is a beginning-to-end write up of the Agile methodology by Miriam Posner, an Assistant Professor at UCLA. She starts with a pov of someone watching an agile team in action, complete with all the user stories, story points, stand ups, a whiteboard, post-it notes, and sprints. For those who have not been introduced to this software development process, ‘stories’ are descriptions of features with ‘points’ showing the difficulty of implementing said features. ‘Stand ups’ are start-of-the-day meetings done standing up for quickness, the whiteboard is to organize each story point, represented by post-it notes, into the stages of ‘in-progress’, ‘done’, ‘backlog’, etc. ‘Sprints are just quick two week long work periods that help to break down the project into digestible chunks.

While this might seem rather much from to some people, others might have an opinion closer to Miriam, who found it to be efficient and intriguing. As such she researched the origins of Agile and learned the complicated history of managers and software developers. I will try to keep this summary brief while hitting all the major points.

Miriam starts with the buildup to Agile. It started in the 50’s and 60’s, most ‘experts’ said building the computer was the hard part and programming it would be trivial. The sheer enormity of their incorrectness led to a push in the field to adopt the name (and stricter processes) of engineering, leading to the coining of the term ‘software engineering’. The idea was that by following engineering techniques the experts would “transform the arcane and error-prone craft of computer programming to meet the highest standards of the engineering profession.” The next people to step in were the businesses who looked to hire these new ‘software engineers’. They created a framework of control where one person defines the project and breaks it up into steps, which are in turn handed to engineers to build and test before moving on to the next step. This was derogatorily called the “waterfall” method, so of course upper management took the name and method and ran with it. This method started to fail due again to people who were not programmers believing they knew what programming entailed. The main problem was that whenever any issue came up in the code, every step needed to be redone which meant the timeline would be increasingly muddled.

Next came Agile, created by “17 middle-aged white guys dressed in khakis and dad jeans” in the Agile Manifesto. In their words:
We are uncovering better ways of developing software by doing it and helping others do it.

Through this work we have come to value:

Individuals and interactions over processes and tools

Working software over comprehensive documentation

Customer collaboration over contract negotiation

Responding to change over following a plan

That is, while there is value in the items on the right, we value the items on the left more.

I would like to continue this dive but I am out of words.

Have a good day.

Link:
https://logicmag.io/clouds/agile-and-the-long-crisis-of-software/

From the blog CS@Worcester – Coder's First Steps by amoulton2 and used with permission of the author. All other rights reserved by the author.