Category Archives: Week 10

Be the Worst

For this week’s blog I decided to talk about the pattern from chapter 4 called “Be the Worst”. This pattern describes the situation where you have taken every opportunity to learn and eventually have outgrown your team. In this situation, it is important that you find developers that are better than you. When you take this route you will need to put in a lot of work because your aim is not to stay at the bottom but work your way up. You will be able to use multiple methods like mimicking other developers until you are on the same level and them. 

I agree with the solution for this scenario. I have found that I learn a lot when I am the weakest on a team. I am able to study the code written by the stronger members of my team and get insight on their choices. I found that learning from another person also speeds the process along. During this process, its important to avoid bothering your other team members too much. Although it can be convenient to just ask others, you need to establish a way to learn on your own so you can avoid prohibiting thew progress of others.

As one can guess, this method has risks like dragging the team down and running the risk of being fired because your productivity is not as expected. I have experienced pressure to avoid bringing the team down along with a lack of confidence in my own abilities. The first steps to follow this pattern is to develop confidence in yourself and focus on learning. Second, I think it is important to have open conversations with your team members and speak up when you may be falling behind. As mentioned in my other blogs, I have worked on past teams where I had to learned from other members. During this process, we all kept each other updated on our progress and it was crucial for us to work together to finish by our deadline.

 I think this pattern aligns well with the way I’ve been developing my professional skills and I cant say that I disagree with anything. Following this path will definitely help with self-assessment because the more you know, the more you know what you don’t know. 

From the blog CS@Worcester – Live Laugh Code by Shamarah Ramirez and used with permission of the author. All other rights reserved by the author.

Finding Mentors

This section really emphasizes the importance a mentor can have on someone’s apprenticeship. Guidance from someone who has already experienced the same or similar issues that you are going through is invaluable. On top of that, it establishes what realistic expectations one should have for a mentor. With computer science being such a vast field that is only getting larger, it’s unrealistic to expect one person to know everything about every topic. The last major point the section covers is that the flow of knowledge does not stop at you. An apprentice must be willing and able to pass on knowledge to other apprentices. 

Thinking back to my most impactful teachers and professors, it’s clear to see that their impact comes from their ability to mentor their students.  Having those impactful mentors throughout my education is what inspired me to seek a career in computer science. The best example I can come up with to relate the impact a mentor can have on an apprentice is this: Imagine trying to solve a hidden picture puzzle or “Where’s Waldo” and you can’t seem to figure it out. Having a mentor is like having a magnifying glass to help narrow down where you should be looking. This sense of direction is great to focus your efforts into researching helpful information. Considering how large the computer science field has grown.

When it comes to choosing a mentor in the computer science field, it is important to realize how large the field is. I have said it three times now, and I still don’t think that is enough to emphasize it. It is best to try and find a mentor that specializes in the field you want to learn about. Although, from my experiences, a mentor that does not specialize in the same field as you is still worth having. A mentor that specializes in any field can still give you tips on how they got to where they are. With the same mentality of teaching a person to fish over giving them a fish, learning how to learn is better than being taught something directly. With information so readily at our fingertips, the ability to research and find solutions is crucial in our world and especially the computer science field.

Bringing everything full circle is the idea that what separates an apprentice from a journeyman is the responsibility to help teach and mentor other apprentices. It makes sense that as I continue down the long path that there will be others behind me. I, personally, have always loved the spark that my mentors have ignited in me and it would be great to be able to pass that sling to others in the future.

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

Recording the Journey

Pattern Summary:
“Record What You Learn” from the book “Apprenticeship Patterns” emphasizes the importance of documenting and organizing your learning experiences as a software craftsman. It encourages apprentices to maintain a journal or log of their progress, insights, challenges, and solutions throughout their journey of learning and mastering software development.

Reaction to the Pattern:
This pattern resonated deeply with me as it highlights a crucial aspect of professional growth: continuous learning and reflection. What I found most interesting and useful about this pattern is its emphasis on active engagement with one’s learning process. By recording what we learn, whether it’s new programming techniques, problem-solving strategies, or insights from failures, we create a valuable resource for future reference and self-improvement. This pattern has significantly influenced my approach to learning and working in the software development field.

Impact on Professional Perspective:
“Record What You Learn” has caused a notable shift in how I perceive my intended profession and my approach to work. Previously, I often relied on memory or scattered notes to capture my learning experiences. However, this pattern has taught me the immense value of structured documentation. I now see my journal as a treasure trove of lessons learned, growth milestones, and areas for improvement. It has become a tool for self-assessment, goal-setting, and tracking progress, ultimately enhancing my effectiveness as a software craftsman.

Disagreements and Critiques:
While I wholeheartedly agree with the importance of recording what we learn, one potential challenge is maintaining consistency and discipline in documenting every learning experience. Balancing work responsibilities, learning endeavors, and documentation efforts can be demanding. However, I’ve found that integrating journaling into my daily or weekly routine has helped mitigate this challenge.

Overall Reflection:
Incorporating the “Record What You Learn” pattern into my professional journey has been transformative. It has instilled in me a sense of accountability and mindfulness in my learning process. I now approach challenges with a more structured mindset, knowing that each solution, mistake, or insight contributes to my growth. This pattern has reinforced the idea that true mastery in software development comes not just from technical skills but also from continuous learning, reflection, and adaptation.

“Record What You Learn” serves as a guiding principle for aspiring software craftsmen, reminding us that our learning journey is as valuable as the destination. By embracing the discipline of documenting our experiences, we pave the way for continuous improvement, innovation, and success in our profession.

From the blog CS@Worcester – Hieu Tran Blog by Trung Hiếu and used with permission of the author. All other rights reserved by the author.

CS448 Software Development Capstone – Apprenticeship Patterns: “Be The Worst”

This week, I wanted to reflect on my habit of self-comparison in relation to my ability as a software developer. I’ve recently found myself preoccupied with how much I don’t know as compared to others in the computing world, both at and above my perceived level of competence. It feels awfully paralyzing comparing my present knowledge with the unfathomable set of things that I’m not even aware that I don’t know about. It’s becoming difficult to even take a break from ruminating about how far behind I feel, because Youtube and Instagram’s content generation algorithms keep delivering me videos with sensational titles like “5 Sorting Algorithms You NEED To Know”, or “Learn THIS Framework NOW”, or “Build THESE Projects To Establish Your Software Career”. It’s exhausting! Before I’ve even started, the amount and complexity of the work that I believe lies ahead of me makes me feel hopeless. How am I supposed to learn anything or get anything done if I think that my best is so far from acceptable, and to do better sounds so exhausting as to be impossible?

Spending so much time and energy spinning my wheels over this issue has me considering a counterintuitive approach. I can’t stay here in this weird superposition of feeling like I’ve been spending all my available energy on becoming the best programmer I can be, yet also feeling like I’m not working nearly hard enough to produce results that anybody would pay me for. That’s why the title of this pattern from chapter 4 of “Apprenticeship Patterns” caught my eye. I knew before that striving to be the best would be a fruitless and frustrating endeavor, but I didn’t foresee that striving to be my best could still lead to as much paralysis and burnout.

I’ve held myself back from contributing to open-source projects or joining online programming groups partly because I’ve been afraid that even if I try really hard, my best won’t be good enough. My rate of output will sputter, and my code will be full of mistakes, then I’ll lose the respect and patience of my team, and soon I’ll be drowning with no hope of rescue. That’s what my imagination says, anyway – it’s annoyingly silent about what my life would be like if I put some confidence into the skills I’ve learned and started believing that people wanted me on their team. This pattern, “Be The Worst”, asks the apprentice to embrace their role as the worst member of a team they are considering joining. From this place as the weakest member of the team, the apprentice can soak up knowledge and experience from their more capable team members and work their way up.

This pattern is one of those in this book that I think goes back to learning to let go of your own ego and presumed sense of competence. I need to be getting more programming experience outside of school, but because I am so petrified of people thinking that I’m incompetent, I never actually get anything done. It’s kind of terrifying to imagine myself as the weakest member of a team working on an important project, because then I imagine the situation where my being on the team has become a burden on the project despite my best efforts and intentions, and now everyone is mad at me when I’m trying so hard! I should have known better than to bite off more than I can chew! Extremely unproductive and exhausting attitude, I know. Maybe I’ll be able to wade my way out of this strange emotional swamp surrounding my sense of industry someday, but maybe more likely is that I’ll end up living that situation where I’m the worst on the team and I just cannot find it within me to do any better than I already am, and I’ll have to learn that regardless of all that, I’m still valuable.

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

Week 11

Deciding on a topic this week I decided to delve into Test Driven Development (TDD). I found an article with an engaging title “Test-Driven Development (TDD): A Time-Tested Recipe for Quality Software” by Ferdinando Santacroce. This would be very useful for me and the whole class because it’s fresh in our minds and we will continue to work with this concept. Getting a firmer grasp on this topic will help me with future assignments and homework. It’s always great to get an insider view with experience inside the field connecting it to what we learn in class.

This article begins with the history of TDD giving credit to Kent Beck one of the first “extreme programmers”. At the time nobody had ever reversed the idea of testing starting with a test instead of the actual code. The purpose of writing a test before the code would help programmers put them in the perspective of the maker making it easier to create the software. This would make more tunnel-focused code with much more simplicity because of just focusing on the test. Plus the codes get rapid feedback because all the tests have been made. TDD has the fastest feedback loop only surpassed by pair programing. Currently, TDD is widespread inside the field and several teams utilize it day to day. It’s hard to adapt to this type of coding scheme but with time it is proven to be a key to success. Minor grievances may also come up because this type of process can be too rigid or the lack of tools.  

After reading this article getting a glimpse into the history of how this came to be. It didn’t specifically specify when it started but I assume it was around the 90s because it mentions how common it is now. Understanding the benefits of doing this test answers my question why would you decide to do your coding process in reverse? What we have been learning is that it will be conventional to have code and then write the test connected to the already processed code. The benefits of cutting down time because of the faster feedback times and leading to less complicated code, I now understand its purpose. That is a recurring theme with code the simpler the better because you are never working alone. Maybe it is a self-contained project but your future self may not understand your complex code and updates to the code should be easy to do not a headache. 

https://semaphoreci.com/blog/test-driven-development

From the blog cs-wsu – DCO by dcastillo360 and used with permission of the author. All other rights reserved by the author.

Enhancing Code Quality: A Dive into Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis in JUnit

In the world of software development, ensuring code quality is paramount. It’s not just about writing code that works; it’s about ensuring that the code is robust, reliable, and maintainable. This is where various testing methodologies and tools come into play. In this blog post, we’ll explore three crucial aspects of code quality enhancement in JUnit: Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis.

Smoke and Acceptance Testing: Smoke testing, also known as build verification testing, is a preliminary test that focuses on ensuring that the most critical functionalities of an application work. It aims to identify fundamental issues that might hinder further testing. Acceptance testing, on the other hand, evaluates whether the software meets the acceptance criteria and is ready for release.

JUnit, a popular testing framework for Java, offers robust support for both smoke and acceptance testing. Through annotations and assertion methods, developers can easily write tests that verify the functionality of their code. By running these tests regularly, developers can catch regressions early in the development cycle, thereby ensuring a smoother development process and a higher quality end product.

For further information on Smoke and Acceptance Testing, you can refer to the documentation here.

Exploratory Testing: Exploratory testing is a hands-on approach where testers explore the software application without predefined test cases. Instead, testers rely on their domain knowledge, intuition, and creativity to uncover bugs and issues. While automated tests are valuable, exploratory testing can uncover issues that automated tests might miss.

In JUnit, exploratory testing can be facilitated through the use of parameterized tests and dynamic test generation. These features allow testers to generate test cases dynamically based on various inputs, enabling thorough exploration of the codebase.

To learn more about Exploratory Testing, you can explore the documentation here.

Static Analysis: Static analysis involves analyzing the code without executing it, typically to find potential defects or code smells. In JUnit, static analysis can be performed using various plugins and integrations with static analysis tools like FindBugs, PMD, and Checkstyle. These tools analyze the codebase for issues such as potential bugs, code style violations, and performance bottlenecks, providing developers with valuable insights into improving code quality.

For detailed information on Static Analysis in JUnit, you can refer to the respective documentation of static analysis tools and plugins integrated with JUnit.

In conclusion, leveraging Smoke and Acceptance Testing, Exploratory Testing, and Static Analysis in JUnit can significantly enhance code quality, leading to more robust and reliable software applications. By incorporating these practices into the development workflow, teams can streamline the testing process and deliver higher quality code with confidence.

From the blog Discoveries in CS world by mgl1990 and used with permission of the author. All other rights reserved by the author.

Week 10 Blog Post

Searching for an article this week I looked for something relating to mocking. Considering last week I did the negatives on mocking I think it’s valuable to have various perspectives. Seeing multiple ideas with mocking can give us an idea of how to implement them in the future. The writer of this article is a reliable source being a Java script developer. Getting information from someone in the industry can give a perspective inside the workforce and how people inside see different ideas. Not everyone may agree with using the same coding language but seeing how developers see different concepts can give an idea of the drawbacks to stuff and where in our own experiences can we improve. Overall this article is a great way to see how mocking is seen inside the workforce by an experienced professional.   

In this article, Eric Elliot focuses on the drawbacks of excessive mocking. He points out how brittle tests and how they can be easily broken. There broken simply just from the change of implementation even though the behavior stays the same. Another point is a false sense of security because of there lack of accuracy that occurs from not using accurate real behavior. This is a fault in the test because the test will pass even if it isn’t supposed to. Third, he focuses on complexity overload which is just adding too much complexity can make the code harder to understand and maintain. Elliot still believes in mocking but a more balanced approach can overall help the program. Mocking should be used sparingly and when there actual weight for its use. All together Elliott wants the audience to create a strategy that will have confidence in their code correctness while also minimizing any negatives of excessive mocking. 

Reading this article at first I thought it would be more of a pro mocking but it’s more in between. It says its flaws while still sharing the positives. After reading this article I understand that mocking can cut time but it can bring flaws to testing. The best time to utilize mocking is when time is scarce and later it can updated with time. It still isn’t the ultimate be-all to testing but with a balance, it will work. Understanding these flaws can foresee issues that may come up when mocking. Mocking should never bring up complexities that can complicate the code and should always have a priority in simple to understand and easy maintenance.

https://medium.com/javascript-scene/mocking-is-a-code-smell-944a70c90a6a

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

Understanding Software Test Doubles

Dummies, Stubs, Spies, Fakes, and Mocks

Software testing is a crucial component of the software development lifecycle, ensuring that your application functions correctly and meets user expectations. One of the key concepts in unit testing is the use of test doubles, which help isolate the system under test (SUT) by replacing its dependencies. This isolation is essential for creating effective and reliable unit tests. In this blog, we will delve into the different types of test doubles: Dummy, Stub, Spy, Fake, and Mock, and explain their roles and usage with examples.

Dummy Objects

A Dummy object is the simplest form of a test double. Its sole purpose is to fill parameter lists without actually being used in the test itself. Typically, a Dummy can be a null object or an instance with no real logic, used just to satisfy method signature requirements. For instance, when testing a method that requires an interface which the test doesn’t interact with, you could pass a Dummy implementation of this interface. However, a Dummy should never affect the test outcome.

Example:

In this example, dummyBoard is a Dummy since the test does not interact with it beyond instantiation.

Fake Objects

Fakes are more sophisticated than Dummies. They have working implementations, but usually take shortcuts and are simplified versions of production code. Fakes are particularly useful when testing interactions with external resources, like databases. Instead of connecting to a real database, you can use a Fake object that simulates database operations.

Example:

Stubs

Stubs provide canned answers to calls made during the test, usually not responding to anything outside what’s programmed in for the test. They are used to supply the SUT with indirect input to test specific scenarios.

Example:

Mock Objects

Mocks are used to verify interactions between the SUT and its dependencies. They can assert that objects interact with each other in the right way, making them a powerful tool for behavior verification.

Example:

In this case, mock is used to ensure that the Module correctly logs messages when an exception is thrown.

Spy Objects

Spies are similar to Mocks but are used for recording information about how they were called. They can be used for more complex scenarios where you need to assert that certain methods were called a specific number of times or with certain parameters.

Example:

Here, spyLogger acts as a Spy, recording the number of times Log was called.

Understanding the differences between Dummies, Fakes, Stubs, Mocks, and Spies and when to use each can significantly enhance your unit testing strategy, leading to more maintainable and robust code. While these tools offer great flexibility, remember that the ultimate goal is to write clear, concise, and reliable unit tests that effectively cover your code’s functionality.

https://dipakgawade.medium.com/mocking-for-unit-tests-understand-the-concept-221b44f91cd

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

Mocks and Stubs

Testing is an important part of coding, and software development. Sometimes though, testing can be tedious work, and creating tests that work properly according to your code can be difficult. This should be the case anyways, as testing is a key aspect to software development, but what if you could do this process a bit more quickly. Creating mocks and stubs can be a good alternative, especially if multiple people are working on different parts of the same project or software. 

In this blog post, June Jung touches upon mock and stub testing. They describe mock testing as “creating a fake version of an external or internal service that can stand in for the real one,” and stub testing as “creating a stand-in, but a stub only mocks the behavior, but not the entire object.” The whole idea of mocks and stubs is to create a fake or a stand-in that does not do anything. This may seem strange, having completely useless methods and functions, but the thing we want to test for is the interactions between the methods and functions. Seeing whether or not they return the correct return values, call the correct methods, etc. This will reduce the amount of time needed to test the functions, compared to testing full, complete functions and methods. Jung says that by using mocks and stubs, you can “reproduce more complex scenarios more easily. For instance, it is much easier to test the many error responses you might get from the filesystem than to actually create the condition.” Jung says this specifically for unit + component testing, but this principle can apply for any kind of testing. In fact, they touch upon multiple cases where mocks and stubs can be used, such as internal functions, integration testing, and contract-based testing. They also provide code examples, and graphs to help you visualize the concept, which can be helpful.

Jung says that as your code grows, your tests should as well, meaning you shouldn’t continue to use the same tests as you continue to write more code, losing the mocks and the stubs. That being said, they’re good to help start, providing a base to continue with. Jung’s blog post is a good resource, as they also have linked another post that goes into the difference between mocks and stubs. It also appears that their blog post is part of multiple posts, which may be worth looking at for more information.

From the blog CS@Worcester – Cao's Thoughts by antcao and used with permission of the author. All other rights reserved by the author.

copyright licenses

We’ve covered software licenses a fair amount in our Software Process Management course. The MIT license, Apache License, and GNU GPL were the most notable for different reasons, but I figure that there are far more licenses that we haven’t necessarily gone over directly in class. I wanted to take the time to familiarize myself with some of these licenses.

Starting off with a CopyLeft license (a type of license I find myself fairly sympathetic to for the sake of keeping software open source), the Mozilla Public License, or MPL, is a weak sort of CopyLeft. According to this post on fossa.org, this means that users must disclose changes, but for a much narrower set of code for each change, file-based for short. When compared to the LGPL, a notable weak copyleft license, the MPL allows users to sublicense as an additional permission. Notable uses of this license are, of course, Firefox and Thunderbird, along with LibreOffice. I do like the idea of having a middle ground between being completely permissive and also wanting to “spread” open-source.

BSD Licenses are permissive licenses that generally have no restrictions. This license seems to fall in line with the big permissive licenses (like MIT) and doesn’t have a viral effect, but requires a copy of the license and a disclaimer of liability. According to a post on AppMaster, the differences between the MIT licenses and the BSD licenses is there being no requirement for a liability disclaimer for the MIT license, no requirement for patent protection on the BSD license, the BSD license being compatible with GPL, and the MIT license requiring a permission notice. I don’t like the lack of patent protection with this one, I know that’s been a fairly annoying issue in the past for various projects.

Lastly, I took a look into the OpenSSL license, as it was on the front page of tldrLegal. Funnily enough, it’s a license styled off of the BSD license, with the express purpose of being used with the OpenSSL project. On the aforementioned tldrLegal page for the license, it mentions in the summary that the license has a special advertising clause, which means that ads mentioning the software in any way must acknowledge the use of OpenSSL. The takeaway, for me, is that if you know exactly what you need with your license, and one that exists has everything you’d like except for one specific requirement or permission, you can build off of that license with that added requirement or permission (assuming that you have a legal expert of some sort write it, I’m assuming).

Overall, I really appreciate the work that has been done to ensure that we have a variety of different ways to license our software depending on what we want done with it. It’s definitely an important aspect of open-source development, and having the resources to find licenses that are closest to the project’s vision is an excellent way to focus on the development and not have to worry about the legal stuff.

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.