Monthly Archives: May 2021

Apprenticeship Patterns: Dig Deeper

Another issue I have been facing as of late is related to my understanding of the systems and software that I use. I often find that I am able to learn just enough to meet the requirements for my assignment, but lack perspective of exactly what is going on behind the scenes. One class in particular that this was true for would be data structures, which was quite challenging considering I had no experience with any facet of it before then. This resulted in me learning exactly what I needed, nothing more or less, to succeed. Upon reflection of this class, I decided to choose the Dig Deeper pattern to discuss this week.


The first major tip given is one that I have often encountered in other patterns, being to break a problem down to its most abse form. As stated in the pattern, most programming issues can be broken down to an incorrect algorithm. Once the problem is broken down, you can examine each part of the problem in great detail, giving you a more in-depth understanding of both the problem and the tools used to solve it. Furthermore, the pattern states that you should focus on reading as much original documentation as possible since many articles may lose some information in translation. As for retaining knowledge, once again breakable tools are referenced, which I have discussed further in a previous post. Any new understanding can be represented in the form of a fun hobby program or blog post. Throughout the process of reading these patterns I have realized how interconnected they are, often relying on each other to result in well rounded software design principles.

One thing to note is that it does feel a bit strange to try and relate to these patterns, particularly because they are very clearly written for someone currently in the workforce in a software development position in mind. Regardless they still have some knowledge that will likely benefit developers at a variety of levels. This perspective being less relevant to me is my only real complaint, other than this I have found these patterns quite helpful! This will be my last post for the time being, but after everything I have ready I may have to return to this blog later on. Thank you for reading and, as always, if you want to read this yourself it will be linked below!

Source

https://www.oreilly.com/library/view/apprenticeship-patterns/9780596806842/ch06s04.html

From the blog CS@Worcester – My Bizarre Coding Adventures by Michael Mendes and used with permission of the author. All other rights reserved by the author.

Mutation Testing

Hello and welcome back to my final blog post of the semester. As we have come to the end now, the last topic discussed in class was one of the most interesting in fact. The name alone, really sticks with you and catches your eye. But what does “Mutation Testing” mean exactly?

Mutation Testing is a type of software test in which you would change or “mutate” certain parts of the source code to see if your test code is adequate and is able to detect the proper errors in the code. Interesting concept here but how would this be done?

After coding the program and creating test code, we still need to figure out if the test code is adequate here. Therefore with this method, we would create alternate versions of the source code which is called a mutant with a single fault in each one to test how efective our test cases are. The test cases are then applied to these mutant programs and you must compare the result. The goal of Mutant testing is for the mutant to generate different outputs with the test cases and if it does not, then you keep the Mutant code alive and need to create better test cases until different outputs from the original are generated.

Now, the first thing that really came to mind when going through this idea was, “Wow, thats pretty interesting and it does make a lot of sense, ill start to try that from now on. But wait, this sounds like it could add hours to my programming, which seems pretty inconvenient so maybe not.” Inconvenient indeed, which is why Mutation testing more or less died after its developement in 1971 but with Automation tools like Stryker and PIT, mutation testing has once again picked up steam in the software testing world.

Sources: https://www.guru99.com/mutation-testing.html#:~:text=Mutation%20Testing%20is%20a%20type,fail%20the%20mutated%20source%20code.

From the blog CS@Worcester – The ways of the Computer: A Blog by JTekelis by jtekelis and used with permission of the author. All other rights reserved by the author.

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.

From the blog cs@worcester – Coding_Kitchen by jsimolaris and used with permission of the author. All other rights reserved by the author.

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.

From the blog cs@worcester – Coding_Kitchen by jsimolaris and used with permission of the author. All other rights reserved by the author.

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.

From the blog cs@worcester – Coding_Kitchen by jsimolaris and used with permission of the author. All other rights reserved by the author.

Automated Testing

Automated testing is a great option for repetitive tests such as regression and functional testing but not useable for testing methods such as discovery and usability testing that requires a human to do the work. If used correctly, automated testing can save a lot of time and therefore money. If used incorrectly, it could end up costing more than manual testing.

Certain requirements that the testing process to be automated must meet are that it is repeatable, determinant, and non-opinionated. The first requirement, repeatable, means that it must be ran more than once, or else there would be no reason to automate it. Repeatable tests have three steps: set up the tests with data and environment, execute the function and measure the result, and clean up the data and environment after testing. The second requirement, determinant, means that the outcome will be the same every time the function runs with the same input. For example, when inputted 1 and 2 to an addition function, the outcome 3 must be produced every time it is ran with those inputs. The third requirement, non-opinionated means that there must be a concrete answer. You cannot automate opinionated feedback.

Now that we talked about the requirements of automated testing, now we will discuss the three steps of automated testing: prepare, take action, and report results. In the first step, prepare, you set up the data and test environment where the tests occur. This will require either manipulation of the data or putting the program in a certain state, or both. The second step, take action, the driver will run the tests. This will happen by calling the code directly, or accessing a programs api or user interface. And lastly, report results. The automated system will record and report the results from the test.

When used properly, test automation can save money and time and provide quality test results.

Source:

Testim. (2020, February 03). What is test automation? A simple, clear introduction. Retrieved May 03, 2021, from https://www.testim.io/blog/what-is-test-automation/

From the blog CS@Worcester – Austins CS Site by Austin Engel and used with permission of the author. All other rights reserved by the author.

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.

Sources:

http://www.mcr.org.in/sureshmudunuri/stm/unit2.php

https://ifs.host.cs.st-andrews.ac.uk/Books/SE9/Web/Testing/PathTest.html

https://www.geeksforgeeks.org/path-testing-in-software-engineering/

From the blog cs@worcester – Coding_Kitchen by jsimolaris and used with permission of the author. All other rights reserved by the author.

JaCoCo

After taking a quick look at JaCoCo in class I wanted to learn a bit more about it. This article is an introduction to using JaCoCo and gives some good examples.

The article explains that when you write tests there are some criteria to consider:

  • We want to make sure that the parts of the code that are best tested are the parts that are most likely to contain bugs.
  • We want to focus our tests on parts of the application that are critical, the parts where bugs are most likely to lead to a bad outcome for our customers.
  • We don’t want to write tests that repeatedly cover the same areas of the code while ignoring other parts of the code.

You can find which parts of the code are the most likely to have bugs by finding the most complex parts. A common way to do this is using cyclomatic complexity (check the article for the algorithm).

JaCoCo measures code coverage, can report on the complexity of each method, and can tell you how much complexity is untested. In the article a lot of the things we covered in class are repeated, but it helps to see it again to reinforce the concepts and also to reference for the future. While we spoke about it in class, a lot of the things that are said are not recorded anywhere.

The article also brings up the use of JaCoCo to measure complexity. After getting as much code coverage as possible you can refactor your code if the complexity score is too high. In the example they reduce a method’s complexity from 21 points to 9 points. That just goes to show how useful JaCoCo is. After reducing complexity and improving code coverage you can be confident your code is ready for a code review.  

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

Static vs. Dynamic Testing

Software testing falls largely into two categories: static and dynamic. Both are valuable, but the scenario around the test being performed determines which method best fits.

Static testing is a testing technique that does not require the code to execute. This can include manual or automated reviews of the code, requirement documents, and document design, all of which are intended to catch errors in the code. Static testing is done in order to prevent errors during the early stages of development and can help locate errors undetected through dynamic testing methods. Reviews are an important facet of static testing and are the primary method for carrying out a static test. A review is a meeting or other process aimed at locating flaws and defects in the design of a program. Apart from physical walkthroughs of the code, there exist tools that automatically search for errors. These tools, such as CheckStyle and SourceMeter, can help developers adhere to standards in code and style.

Dynamic testing is a testing technique that checks the program’s behavior when code is executed. As the name suggests, it is intended to test the dynamic behavior of a software. This encompasses a vast majority of the testing methods we’ve discussed both in this class and on this blog. The two types of dynamic testing are white and black box testing, which are both techniques that I have discussed on this blog before. Dynamic testing ensures that a software is working properly during and after its installation, it makes sure that the software is stable, and it encourages consistency in the software’s functionality.

Sources:
https://www.guru99.com/testing-review.html
https://www.guru99.com/dynamic-testing.html

From the blog CS@Worcester – Ciampa's Computer Science Blog by graceciampa and used with permission of the author. All other rights reserved by the author.

Concept of Mocking

Mocking is the process of just focusing on the code that needs to be tested not at all whats going on with the behavior of the outside dependencies. Therefore we sort of use a cheat code here, we use replacement objects ro kind of replicate the behavior of the real external more complex code. Immediately, this loophole has caught my attention as this seems like a great work around and will make my time creating test code much more efficient. And were all about efficiency when it comes to coding.

Back to the matter at hand, we should go over the three types of replacement objects. This objects include, Fakes, Mocks and Stubs. As a lot of information is rolled out onto us using these concepts i find it important to take a little time to really simplify what each of these terms mean.

A Fake is an object that has actual working code but returns a predicatable result, but “will not implement the actual production logic” (https://www.telerik.com/blogs/30-days-of-tdd-day-11-what-s-the-deal-with-mocking). In addition, a Stub is an object that will test specific inputs for some rather specfic results. The problem with a Stub is just that though, its too specific so once your begin to change inputs, the stub will begin throwing exceptions. Then lastly is where the much more sophisticated Mock comes into play. A Mock is similair to a Stub but also able to control how many times methods are called, in what order and with what set of data as well.

To conclude here, this overall concept of mocking using replacement objects, are used not to subsitute unit testing, but instead they isolate the dependencies, making test code more focused and efficient. There it is, efficiency, the holy grail of words when it comes to coding and that is the number one reason Mocking is used.

Source: https://www.telerik.com/products/mocking/unit-testing.aspx#:~:text=Mocking%20is%20a%20process%20used,or%20state%20of%20external%20dependencies.

From the blog CS@Worcester – The ways of the Computer: A Blog by JTekelis by jtekelis and used with permission of the author. All other rights reserved by the author.