We must learn how to learn.

Learning is ongoing, continual, without end.

 [L]earning about what we do not know is often more important than doing things we already know how to do.

—Jim Highsmith, Agile Software Development Ecosystems

This chapter focuses on continual growth as a developer. The problem scenario presented in the text is one where we have only a basic skill level of software development as it pertains to our day job. The author suggests that we should take a multifaceted approach to learning.

Some examples of how we can seek-out new knowledge and experiences:

  • Sign up for Google Reader (or another blog aggregator) and begin subscribing to software development blogs. With modern machine translation technologies, you do not even have to restrict yourself to those who write in English. You can follow Tim O’Reilly’s advice and track the blogs of what he calls “alpha geeks” across a variety of technology domains.[26] These people are not necessarily the best programmers, but collectively they tend to sense new trends years before the rest of us. Consider using your own blog to reflect on the themes you pick up from these bloggers.
  • Start following some software luminaries on Twitter and pay attention to what they are working on.
  • Subscribe to a moderately high-traffic online mailing list and try to answer people’s questions by reproducing their issues.
  • Join a newly formed local user group that is excited about a new technology. Do not just attend silently – introduce yourself to the organizer and offer to help.
  • Persuade your employer to send you to a technical conference. Even if they will not pay for you to attend, you can still read the slides on the website and download audio/video of the speeches.

Using multiple tools to acquire knowledge and skill-sets is one of the best approaches I have tried. It is the same if you want to learn a new oral language, you surround yourself with it and continually find ways to incorporate it into your daily routine. Immerse yourself in the topic continually, not just when you are at home sitting with a book. The ending of this chapter resonated with me as the author mentioned how simple it is to take this continual search for more and more knowledge too far. I have a (possibly slightly unhealthy) obsession with learning about a variety of unrelated topics that do not benefit my life in any way.

  When I hear of a new technology or topic that interests me, I become enthralled by it. Nothing else exists until I know as much as I can about it. Currently, my obsession is with 18650 Lithium ion batteries, particularly building my own packs. This pattern will prove to be helpful in my life reminding me not to get lost in the sea of interesting information and to also not lose my practical skills in life/development.


C o d e C o v e r a g e T e s t i n g

Cover your tests

Welcome back, I am going to explain why you should be running most of your tests with some sort of code coverage. Code coverage is a software testing metric that analyzes how effective your tests are when ran with your code. Code coverage enables you to see the degree to which your code has been implemented. It also helps you to determine how successful unit tests are by checking the degree to which your code is covered by them. Code coverage percent is calculated by items tested by dividing elements tested by elements by elements found.

Code coverage enables you to improve the efficacy of your code by having a statistical analysis of code coverage. The test cases your currently running without code coverage may be less effective than you realize. Running with code coverage allows you to identify parts of your software that have not been examined by your test cases. This not only makes better code but it saves time because it gives you a clearer picture of where you need to refactor.

Code coverage enables you to identify parts of the software that are not implemented by a set of test cases.

How is code coverage calculated?

Well, that depends on what tools you’re using. However the common tools combine some of the following types:

  • Line coverage: percent of lines tested
  • Functions coverage: percent of functions called
  • Conditions coverage: percent of boolean expressions covered
  • Branch coverage: percent of branches executed

Are all code coverage types created equal?

When I first learned about code coverage, I assumed that line coverage must be superior, because hitting every line must be most important and probably will include most methods. While this is important it will miss out on a few things. Consider the following code from a stackoverflow answer:

public int getNameLength(boolean isCoolUser) {
    User user = null;
    if (isCoolUser) {
        user = new John(); 
    return user.getName().length(); 

When you call this method with the boolean variable isCoolUser set to true, you will have your line coverage come back 100%. However, this method has two paths;

  1. boolean is true
  2. boolean is false.

If the boolean is true, all lines are executed, and code coverage will return 100%. What we don’t see with line coverage is that if you call this method with the boolean set to false, you will get a null pointer. Line coverage wouldn’t show you this bug, whilst branch coverage would. For these reasons, best practice is to use a coverage tool that examines multiple types of code coverage

You’ve convinced me, so how do I start?

Code coverage comes built into most IDE’s. In intellij, when you open the run drop-down menu, its two buttons below, “Run with Coverage”. I have found this tool incredibly useful/invaluable in my coding. Since learning of it, I have not run tests without using coverage. There have been a few instances where I created test classes that passed but I wasn’t aware just how terrible they could be. Using code coverage has made me learn more and see my mistakes much more easily. Lines I thought were testing the code, I could comment out and see if it reduces code coverage and learn from that. In Intelli-j’s code coverage, lines that have been executed are green while lines that aren’t are red.

Other code coverage tools are listed below:







Good coverage can’t fix bad test writing practices.

If your tests aren’t comprehensive, covering multiple possibilities, coverage won’t save you.

Thanks for taking the time to stop by and read my blog.

I learned quite a bit of information from the following links:






Hello, my name is John Simolaris and I’m currently a student at Worcester State University. Throughout my blog I will share various tools, tips and information I gain along the way to becoming a Software Engineer. In my personal life, I enjoy fixing up old power wheels, strength training, and researching various topics such as neurochemistry, philosphy, poetry, art, pure mathematics, childhood development, etc. Professionally, I am interested in learning software design and penetration testing. From now until the end of 2020, I will be posting about my findings in:

  • Design Principles
    • Object Oriented Programming
      • Abstraction
      • Encapsulation
      • Polymorphism
      • Inheritance
    • Single Responsibility Principle (SRP)
    • Open-Closed Principle (OCP)
    • Liskov Substitution Principle (LSP)
    • Interface Segregation Principle (ISP)
    • Dependency Inversion Principle (DIP)
  • DRY (Don’t Repeat Yourself)
  • YAGNI (You Ain’t Gonna Need It)
  • GRASP (General Responsibility Assignment Software Patterns)
    • Controller
    • Creator
    • High Cohesion
    • Indirection
    • Information Expert
    • Low Coupling
    • Polymorphism
    • Protected Variations
    • Pure Fabrication
  • “Encapsulate what varies.”
  • “Program to an interface, not an implementation.”
  • “Favor composition over inheritance.”
  • “Strive for loosely coupled designs between objects that interact”
  • Principle of Least Knowledge (AKA Law of Demeter)
  • Inversion of Control
  • Design Patterns
    • Creational
    • Structural
    • Behavioral
    • Concurrency
  • Refactoring
  • Smells
    • Code Smells
    • Design Smells
  • Software Architectures
    • Architectural Patterns
    • Architectural Styles
  • REST API Design
  • Software Frameworks
  • Documentation
  • Modeling
    • Unified Modeling Language (UML)
    • C4 Model
  • Anti-Patterns
  • Implementation of Web Systems
    • Front end
    • Back end
    • Data persistence layer

Concrete Skills

Having knowledge is not the same as having the skill and practical ability to apply that knowledge to create software applications. This is where craftsmanship comes in.

—Pete McBreen, Software Craftsmanship

This chapter presents the scenario where you are trying to join a talented team of developers that will provide you a great opportunity for growth and development as a developer. The problem is that the team has no obvious net benefit to hiring you and there most likely will be a net loss for a while as the team attempts to get you up to speed on your skills and ability to mesh. There is also a chance that you are not able to indirectly contribute to the group with things such as automating simple manual tasks.

The solution presented in this scenario is that we should acquire and maintain concrete skills. Having a solid grasp and fluency in a specific language, framework, etc. will help demonstrate to the hiring team that you have value to bring to the team. If you are unable to contribute directly in the beginning, you can contribute indirectly while you transition into your role with the team utilizing your concrete skill/s.  Having concrete skills will reassure future coworkers that they will not need to hold your hand and walk you through all your work every step of the way.

The action plan set forth in the reading, is that we should look at the CVs of people whose skills we respect and identify which skills listed on their resume would be useful for us to have on ours. Although I am familiar in knowledge of bash script, javascript/vue, C++, and SQL. I would benefit from solidifying this knowledge into skills that can be easily demonstrable in an interview without requiring any google searches. To further solidify my grasp on these concepts into concrete skills I feel confident about, I can practice leetcode problems, and create websites for small businesses that do not currently have one.

Retreat into Competence

The problem talked about in this pattern is being overwhelmed with how little we know. I have felt this way many times, pursuing a degree in compSci. There have always been students in my classes that are better developers than I. Whether they have been programming longer than I have, or they are not juggling school with fatherhood, home maintenance, cooking for five, cleaning, paying a mortgage etc.

The solution presented in the text is that we should occasionally retreat for brief intervals into the things we are competent in. Taking some time to build something in familiar languages and frameworks will help ground us in our abilities . We are warned however that going backwards can be risky, if done without proper planning. When going backwards, it is best to set specific time limits for yourself so you don’t get stuck in your comfort zone. We desire comfort and familiarity, but growth does not exist within your comfort zone.

All throughout my life, asking questions to better understand things I am somewhat familiar with or inquiring about things I am not familiar with, is something I have always done. During my time studying to become a developer, I have experienced this feeling of overwhelm from time to time, regarding my ignorance in computer science. Due to my passion for learning, I have sought support and guidance from professors and peers alike, without hesitation. Although this has benefited me greatly in the past, it could be quite useful to retreat for timed intervals doing something I know well and feel confident about.

The idea of setting time limits interests me because it reminds me of Pomodoros, which is something I utilize quite frequently. Setting a timer to work on “task A” and another timer to step back and take a break has been working well for me. Taking that break and using it to do something I am good at and know well could very likely give me the reassurance I need in respect to my knowledge and abilities as a developer. Maybe even developing something I feel competent and confident in would help me to ground myself as a developer.

Path Testing

Hello, and welcome back to my blog.

This week I will be sharing what I have been learning about path testing. Path testing is a white box method of tests that is used to design test cases by using the source code of a program to find every possible executable path. The bug presumption for path testing is such that the program has gone wrong in some way, causing it to follow a different path than desired.

Path testing utilizes Cyclomatic Complexity to establish the quantity of paths, and then tests cases for each path are generated. Developers can choose to execute some or all paths through when performing this testing. Path testing techniques are perhaps the oldest of all structural test methods. Path testing is most useful for unit testing new applications.

It provides full branch coverage, but does so without covering all possible control flow graph paths. The four part process to path testing begins with drawing a Control Flow Graph of the software that is being tested. Next, Cyclomatic Complexity of the program is calculated based off Edges, Number of vertices, and Program factor. Now, we can use the data calculated in the first two steps to find a set of paths to test. The computed cyclomatic complexity equals the set’s cardinality. Finally, we will develop test cases for each of the paths determined in previous steps.

Path Testing process:

Path testing is beneficial because it focuses test cases on program logic. It helps to find all faults within the code and reduces redundant tests. In path testing, all program statements are executed at least once. Thank you for taking the time to visit my blog and join me on my growth as a software developer.





Data Flow Testing

Data flow tested is used to find issues such as:

  • a variable that is used but never declared
  • a variable that is declared but never used
  • a variable being de allocated prior to its use
  • a variable that is defined multiple times before being used

Some advantages of using data flow testing to find issues in a program include, but are not limited to, finding variables that are used but not defined ever, and finding a variable that has been defined numerous times before it is even used.

Data flow coverage can be classified into the following categories based on “sub-paths” and “complete path”:

  • All definition coverage: Covers “sub-paths” from each definition to some of their respective use.
  • All definition-C use coverage:“sub-paths” from each definition to all their respective C use.
  • All definition-P use coverage: “sub-paths” from each definition to all their respective P use.
  • All use coverage: Coverage of “sub-paths” from each definition to every respective use irrespective of types.
  • All definition use coverage: Coverage of “simple sub-paths” from each definition to every respective use.

Mockito mocking

On the Vogella Mockito tutorial page, there is a brief overview and explanation of what mocking is and what a mock object is. There is a simple diagram showing the sequence of what typically happens when you use Mockito in your tests. This tutorial also mentions that when using the Mockito libraries, it is best to do so with either Maven or Gradle, which are supported by all of the modern IDEs. Here you can also find code examples, and even where to put them in your code. This tutorial is packed with visual representation of the information given and I find that to be extremely helpful.

I would say this particular article/tutorial can be very helpful in bettering one’s understanding of how to use Mockito. It’s filled with tips and simple to understand diagrams, explanations and code examples. It even dives into using the spy() method to wrap Java objects, mocking static methods, creating mock objects (in the exercise provided, you can create a sample Twitter API), and testing an API using Mockito.

I have included in this blog post two other articles I found interesting and informative on the subject of Mocks/Mocking

The Tortoise Always Wins

“How long will it take to master aikido?” a prospective student asks. “How long do you expect to live?” is the only respectable response.

—George Leonard, Mastery

While reading chapter 3 of Apprenticeship Patterns, I stumbled upon the preceding quote. It resonated with me because I often get so caught up in aiming for perfection that progress becomes halted. Anything worth doing is worth doing poorly.  I have heard it said that perfection is the enemy of progress.  

This chapter focuses on the long road we all must travel to master our craft. The author talks about how we have all grown to desire immediate gratification, whether that be in notoriety, wealth, or the development of our skill. If we desire to become true craftsmen we must focus our attention on delayed gratification. Our skills will take time to develop, and the journey will be a test in endurance and patience. The problem presented in the text is of being stuck in a “golden lock” where our aim for further crafting our skill is at odds with our desire for a higher paying job. By taking the path less traveled “Robert frost” we can make all the difference in our development as craftsmen.

We must be patient and compassionate with ourselves along our journey. It is easy to get discouraged when we see how little we know in comparison to veteran developers or even peers. So long as we strive to continuously hone our craft, we can become the masters that future generations of craftsmen look up to. The long road means we do not grow into incredible craftsmen overnight. It takes long hours and is a slow process.  

When we take our time to mindfully develop code, asking questions about why and how code behaves the way it does, or why we approach problems a certain way, we deepen our understanding of not only the development process but our strategies for everyday living. We learn better problem-solving skills, we become more inquisitive into ways to efficiently meet the needs of ourselves, our families, and our communities. This is something I have struggled with as a CS major, trying to balance out good grades with deeper comprehension. Many students fall into the trap of just learning the information required to pass the class with a good grade, putting ourselves at a disadvantage. Our lives have only a finite amount of time, and sometimes we need to decide whether we should slow down and take time to comprehend the deeper truths of software development, even though it may take away from time available for studying the class materials.

If we desire to become true craftsmen rather than just working a 9-5 grind we need to recognize that the path we chose is neither easy nor short. Our field is growing exponentially with the constantly changing technological advances we are experiencing and will continue to experience. This path is not as straight and narrow as other fields, due to the continuous changing of technology. However, if we slow down and dig deeper asking the questions that lead to deeper understanding, we will see the commonalities that all software share, making it easy to adapt to the changing of software development. Traveling “The Long Road” can allow us to bring meaning and pride to our work rather than being another nameless cog in the machine for a corporation.

The tortoise always wins the race.

Sprint Retrospective 2


welcome back.

  In todays blog post I will be writing about my second sprint developing part of my universities food pantry website. My team recently finished the second sprint, during which we focused on developing basic skeleton code with basic functionality in place for future development. I and another teammate worked on the front-end development of the project while one classmate worked on the backend and another person worked on the IAM (Identity and Access Management) Communication among our group occurred mainly through GitLab and discord. At the beginning of the sprint, we mainly had documentation on the concepts we were to begin using and now we have progressed to having multiple branches of skeleton code developed.

During the first sprint, I had begun researching REST API and OPEN API with intentions on developing that area of the project. However, due to personal health reasons I was unavailable for slightly over two weeks and was not sure if a return to the project was possible. Due to these unforeseen setbacks, my team had to switch up task assignment. When I returned, another teammate was tasked with taking on the API design, which meant I was to take on the checkout guest front-end. This set me back even further than anticipated because now I had to switch to doing a completely different part of the development process. I began researching and completing tutorials on Vue.js which ended up being quite a bit to take on whilst trying to develop something presentable with Vue.js for the first time. I learned quite a bit and am happy with the progress I made as a student. I take pride in the development of the Checkout Guest front end thus far. It is linked below under the updatedFunctionality branch:


For the second sprint, our team faced the challenge of applying the knowledge/concepts we gained earlier studying Express, Vue and keycloak and applying it. I was uncertain of how to approach the input validation of the student ID field but ended up modifying some code for an input field. I specifically spent some time verifying that the submit button was disabled unless an input of seven digits was entered. I assumed we would work with the WSU pattern of blue and yellow and designed in this way though I was uncertain of specific design layout and appearance that other teams planned to develop. A member of my team had contacted other teams with questions regarding appearance and then refactored according to the newly acquired information. A small hiccup with practical application is to be expected when developing with new frameworks but I still think we worked well despite the initial chaos of using these new frameworks, especially the combination of multiple frameworks.

To improve as a team, we should become more comfortable and fluid working with these new concepts and frameworks by continually practicing them daily in small increments rather than in large infrequent bursts of use. This would help to solidify these new concepts in our minds and keep them fresh. To improve as an individual, I would benefit from checking GitLab daily rather than a few times a week. This will help me to stay more on top of how the other members of my team are progressing and coordinate with them on challenges or setbacks either of us face before they become a major setback.

Overall, our team is doing quite well despite the setbacks. I am grateful to have the opportunity to work with such excellent developers who have great communication skills, are not afraid to ask questions. We work well as a team, and my teammates have been very cordial with any questions or comments about the design process outside of class hours. As someone who grew up dependent on food pantries like this one, I am honored to be able to dedicate my time to the development of this project.

Thanks for taking the time to stop by.

  • John Simolaris

Learn How You Fail

Failing is unavoidable and it happens to everyone at some point. In reality, anyone who has never failed at anything has either stopped challenging themselves or learnt to ignore their own mistakes.

Your skills are progressing but you are still failing and have some remaining weaknesses. So instead of drowning in a sea of self-pity over previous failures, develop some self-awareness of your own patterns, habits, behaviors, and other factors that play a role in causing you to fail. When you are aware of yourself and the things that mess you up, you give yourself the option of either trying to solve the issues or cut your losses. You cannot succeed in all, and recognizing your shortcomings is critical because it allows you to actively recognize distractions and concentrate on your goals.

Accept that there will be certain stuff you aren’t very good at.

Once you learn to accept your failures you can set realistic limitations on your goals.

Often times I get irritated by the fact I keep failing, but if I accept it, my failures become learning opportunities. I can then seek out guidance and learn new skills from someone who knows more about code than I do. It is hard, honest work to admit your shortcomings and it will take a lot of failures, but I am confident that eventually, it will all be worth the frustration.

Breakable Toys

Experience is built upon failure as much as (if not more than) success.

Breakable Toys is about purposefully creating learning opportunities by pushing yourself outside of your realm of experience and designing and developing complete software projects on your terms. The concept of this pattern is one that I speak of frequently, in regards to many areas of life. The comparison of the jugglers was actually pretty insightful. It would not make sense to attempt something new, knowing you may fail without having practiced it first. As the saying goes, “Practice makes perfect.”, and this is especially so in software development.

Trial and error seems to be an obvious concept whenever learning something new. Although, it does not seem likely that one would have room for many failures in software development, as that would become costly. With that thought in mind, the suggestion to build your own systems on your own time – your Breakable Toys – is ingenious. Within that suggestion, one of the Breakable Toys given as an example in the book Apprenticeship Patterns is to create a personal Wiki page. The book mentions that in doing this, you can gain knowledge in web design, HTTP, concurrency and parsing. Not only that, but you gain experience and a growth in work ethic, confidence and pride in yourself and your work. An equally beneficial reason to create a personal Wiki page is that it is a perfect way to keep a record of what you learn.

Breakable Toys is a pattern I can see becoming one of the most useful patterns I’ve learned of thus far. With knowledge of this pattern, I am confident that with hard work and dedication – and more than likely a whole lot of screw-ups – my abilities and confidence as a programmer will progress. Going forward in this field, I fully intend to start building some of my own Breakable Toys in order to enhance my skills and broaden my understanding of software development. I would encourage other programming students and programmers alike to invest their time in building their own Breakable Toys.