Category Archives: Week 13

Black/White box testing

I am writing in response to the blog post at https://www.guru99.com/back-box-vs-white-box-testing.html titled “Black Box Testing Vs. White Box Testing: Key Differences”.

Black box testing and white box testing are topics that we have covered in the CS 443 software quality assurance and testing class. Black box testing involves testing from the perspective of a user, who does not have access to the code, and thus the testing is done without referring to the code. Instead, the behavior is tested directly by checking inputs against expected outputs. White box testing involves code coverage and testing different branches and paths of code based on the code itself and not a pre-defined specification for the behavior to meet.

The blog post provides a table of comparisons between black box testing and white box testing. Most of the points are that black box testing is done without access to the code and white box testing focuses on the code. One of the points made is that black box testing is not good for testing algorithms. This makes a lot of sense, and for certain algorithms, black box testing would be impossible to do. Black box testing requires some specification for the behavior of the program to meet, and that specification is supposed to cover everything that might go wrong with the program. This is fine when the program is made up of a set of conditional branches, but something more intricate like a computational geometry or machine learning algorithm would be impossible to test every case for because the number of different paths the code can take is on a completely different scale. White box testing in this case would be the only way to check that the algorithm will work, and that is by proving that it works. The only way black box testing could prove correct behavior would be with an exhaustive proof.

White box testing is not necessarily as easy or convenient as black box testing because it requires understanding and analyzing the code instead of just running it and seeing what happens. In some cases, though, it is necessary to use.

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

AntiPatterns: Golden Hammer

Another day, another blog post about a concept from Sourcemaking.com, this time on the Golden Hammer AntiPattern.

Software Development is a field that requires continuous learning throughout your entire career. With the sheer amount of tools at your disposal, it can be daunting to try to expand your skillset. However, knowing how to utilize as many tools as possible is important to help make an effective and well-rounded developer. Not only that, being brave enough to drop the tried and true way of doing things for newer, more effective solutions is an important soft skill to have as a team.

We’ve all heard of the expression, “If all you have is a hammer, everything looks like a nail.”, and that’s the exact origin this AntiPattern. When a team fails to develop their knowledge and expand their skillset, they often fall back on the same process that they’ve used in the past. Sometimes, a significant financial investment has been made into training the team to use a specific product, and so they don’t want to let that methodology go to waste. That’s fine, except for the fact that there is a unique way to approach nearly every new problem that developers come across. Reusing old system design is a sure fire way to cause more problems than necessary for the development process.

There are countless issues with this approach — it’s like trying to fit a square peg in a round hole. In a way, teams will end up warping the problem in order to make their solution work, as opposed to designing a good solution for the problem. It’s self limiting too, because teams will only end up choosing problems that they feel comfortable with, relating back to approaches they have taken in the past. Not only this, but if the Golden Hammer is a particular product or tool made by another company, then the team can find themselves at the mercy of that company to continue support for that product.

Not only does this AntiPattern require a tremendous amount of refactoring (usually, a complete reworking of the product is necessary), it requires a change in the philosophy of the developer(s). Each and every member of the team needs to be focused on expanding their knowledge of shifting trends in technology, and there must be an emphasis on the exploration of new tools in the workplace with some leeway in deadlines as a result.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

AntiPatterns: Spaghetti Code

Many AntiPatterns seem to arise when code structure is ignored and foundational concepts like those of OOPs are forgotten. Spaghetti Code is perhaps the most common and widespread of these, since it can come about so easily in nearly any program regardless of the language or paradigm. In a general sense, it is unstructured code that is difficult to read, edit, or use.

Spaghetti Code involves a very cluttered, messy design (or lack thereof). There are many moving parts which seem disorganized and generally readability is extremely, low even for the original developer. It’s much more easily found in procedural paradigms as Object Oriented paradigms were made partially to avoid this problem in particular. If Spaghetti code is found in an Object Oriented system, the structure often reflects that of a procedural program.

I’ve written about The God Class before, which is a concept that stems from similar errors, except in a slightly different form. Spaghetti Code differs from this in that the God Class has one central core class that makes extending and modifying anything more of a challenge than is necessary. Spaghetti Code generally has several large classes which run in a single, multistage process. Sometimes this kind of messy code can be found within other AntiPatterns, such as Lava Flow. Dead ends of routes taken with old projects can result in a jumbled mess of irrelevant code that is hanging around for no reason other than it is difficult to read.

So what can we do about it? Well, like many other AntiPatterns, the best solution is to take a preventative approach. Make sure that a clearly defined structure for the program is outlined before starting to develop. Make sure that when modifying the existing code, the developer adheres to the structure in place. If you’ve found yourself in a position where you need to refactor Spaghetti Code, it could potentially be a case of diminishing returns where trying to “fix” the program is more difficult than rebuilding it from the ground up. This is a massive waste of development time and money, since if a clear goal were in place to begin with the problem could have been avoided all together.

At the end of the day, a clear vision and game plan for the software you’re writing is the most important piece of development. Without a path to follow, problems become difficult to solve and solutions become difficult to implement — especially when developing a large scale software system.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

Is Your Interface Two-Faced?

CS SERIES (11).pngWhen coding, users always have to be conscious about the way their code may be implemented or used in the future by different services leading to potential misuse. After reading Code Health: Make Interfaces Hard to Misuse by Marek Kiszkis, it made me think about how important communication between testing code is.

I found this content useful because Kiszkis featured some examples that can show how an interface could be misused easily. The examples included:

  • Requiring callers to call an initialization function
  • Requiring callers to perform custom cleanup
  • Allowing code paths that create objects without required parameters
  • Allowing parameters for which only some values are valid, especially if it is possible to use a more appropriate type

Sam CS (17)It is also good to remember that at the end of the day, code should be defensive but not too defensive to the point that complexity is increased and performance overall is reduced. Kiszkis says “it is not always practical to have a foolproof interface” because there will be situations where some requirements are things that cannot be expressed in an interface.

After seeing so much content based on being careful about what you code it is surprising how this article says it is not necessary to plan too hard. I kind of understand why Kiszkis would say this but personally, I kind of disagree with this. The reason why I disagree is because if someone does happen to end up with more time to work on something than expected and they know it will make something more efficient, then why not go for it?

Overall, I appreciated what was shared in this article in terms of encouraging users to try and see issues that can arise with their code when it comes to interfaces. The main takeaway for me is that if something is brought up, or triggered by undefined behavior, a user should try and make it impossible for this to happen. A way of doing so is by adding things where necessary, like certain slots in his example. It does not have to be too specific but detailed enough so that it covers different aspects, similar to how we try to prepare for everything when it comes to equivalence class testing.


Article: https://testing.googleblog.com/2018/07/code-health-make-interfaces-hard-to.html

 

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

New Instances in JUnit

Martin Fowler’s Blog is an amazing resource for someone breaking into the field of Software Development — his blog posts are extremely easy to read and are very educational. Even older content is still relevant and helpful to read through, like this article on the reasoning and design decision behind JUnit tests creating new instances for each test. As someone who has only a bit of experience writing my own Unit Tests, this was pretty eye-opening.

So why does JUnit create a new instance for each test, and what does that even mean? Each time you run a test, a new instance of each object used in the test is created. This means that in one test, if you create an object or assign a value, that change will not carry over into any other tests. The idea behind this is called isolation, and although it may seem counterproductive, it is extremely important. It ensures that no test should ever do something that would cause another test to fail.

So what exactly makes isolation so important? The point of Unit testing is to bend and stress the basic structure of the source code. If all tests were relying on a shared state which was dynamically changed between one another, each would leave behind data that would impact the other tests. You’d end up testing not just the source code, but you’d also be dancing around the different tests you had already written. If each test weren’t isolated, it would make the main objective — testing the product — significantly more complex.

JUnit in particular provides functionality to support this isolation and make the job of the tester easier — things like the setUp method. If you want each test method to create an Array with 5 elements, you would place that in the setUp method for it to be run prior to each test as opposed to having to rewrite that piece of code for each test you have. This helps keep each test isolated, whilst still providing every test with a shared base state from which to run.

If you’re like me, you had encountered this problem while tinkering around with JUnit and kind of accepted it without questioning the purpose behind it. It’s intuitive and makes sense that each test should be isolated from the others, but it is also important to ask “Why?” or “What would change if this were different?”. It gives insight into the JUnit framework, and helps make a more effective tester.

From the blog CS@Worcester – James Blash by jwblash and used with permission of the author. All other rights reserved by the author.

For agile testing, fail fast with test impact analysis

https://www.infoworld.com/article/3305326/application-testing/for-agile-testing-fail-fast-with-test-impact-analysis.html

Regression testing is testing a piece of software to make sure any changes or additions have not broken any existing functionality. In agile development it is important to release your product as quickly as possible and because of that it is important to fix any failures quickly and efficiently. Developers need feedback as soon as possible but regression testing can take up to days to complete, so they often settle with CI or scale down testing. As a result, productivity is worse and the close to the deadline sprint is more painful. One common approach to speeding up regression testing is to remove end to end testing which causes developers to miss a lot of issues that have a very large impact on the user experience. Risk-based testing is another way organizations speed up the process but many believe it can require too much overhead. However some amount of risk-based testing has to be done in order to guide prioritization on what needs to be worked on.
Test Impact Analysis is a technique that rapidly exposes issues in code since the last time it was modified and tested. It does this by correlating all regression tests to code and select only the tests associated with the latest round of changes. It then orders those tests based on their likelihood of detecting problems and prioritizes the execution of the ones most likely to expose problems. This helps you find a majority of the problems in an extremely short amount of time. This also results in much tighter feedback loops which means failing builds get resoled faster. Test <> code correlation makes it easier to determine where additional tests need to be taken as well as streamline the defect remediation process. Test impact analysis can be applied to any test including unit tests and automated functional tests. With test impact analysis a specialized set of cases is selected and executed. Static analysis finds which code has been modified since the previous test run, then dynamic analysis correlates the regression test suite with the identified code and regression tests that do not touch the modified code are eliminated for the test run. Additional analysis is then run to determine which tests are most likely to expose a defect in the new code and then sorted so that the test most likely to expose the most problems is executed first then merged correlated code coverage from all of the executed tests is visualized versus the new or modified code map, making it simple to spot coverage gaps.

From the blog CS-443 – Timothy Montague Blog by Timothy Montague and used with permission of the author. All other rights reserved by the author.

Apprenticeship Pattern: Record What You Learn

This week I also read the pattern “Record What You Learn”, and this is a pattern that I am not anywhere near doing correctly. I think that this problem is useful, and though not as significantly as the others, still one worth implementing. This pattern is essentially asking you to take notes and record all of the things that you’ve learned throughout your journey. Taking notes does help in learning, but its real power comes when you actually go back and review these notes. The author alludes to the previously mentioned by suggesting that we keep our notes in a medium that we are more likely to access and interact with. Often times notes are taken in a subject specific notebook or application, the problem with this can be actually going back to this material to review it since it may lack that personal touch. This problem can be alleviated by storing your notes in a personal wiki, journal, or blog, the key being that this medium is personal and that it is something we interact with often.

The author emphasized the idea that your notes should be a “nursery, not a graveyard”, meaning that these notes should be a source of progress and growth and not stagnation. Even if you go through your notes daily, if you are only trying to memorize what is in your notes rather than trying to gain new insights and making new connections with them your time could be better spent doing something else. The other great benefit of having these notes is the fact that they act as some sort of wiki for you. The author mentions this and I have seen the truth in that myself. There have been times when there was a problem/bug that I could not figure out and the solution required multiple different things to be done, when I originally learned to solve the problem it may have taken me hours to gather all of the resources and information, but after storing all of those steps in my notes, I do it in minutes. Taking notes can often be too mundane and boring to actually want to do but this pattern has really showed me that it’s worth powering through it. By recording what you learn you have a detailed history of your grown, your own personal archive, and source of future ideas and innovations and because of this I will definitely try to apply this pattern as well throughout my career.

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

Apprenticeship Pattern: Practice, Practice, Practice

This week I read the pattern “Practice, Practice, Practice” and the focus of this pattern is pretty obvious. An expected theme that I came across when reading this pattern was the importance of practice itself, but the author went beyond that and specified the type of practice that is most valuable. The technique of practice that is optimal is said to be “deliberate practice” in which “ a mentor would assign you an exercise based on her understanding of your strengths and weaknesses…”. This method of practice is good because the exercises that you are practicing with match your skill level and most important of all, you are receiving feedback. Depending on your performance, this mentor would then decide whether or not increase the difficulty of the exercises. I can see the value in practicing like this, a big thing stopping me and many others from going back and practicing is how boring and mundane it is and this method ensures that you are amply challenged.

Another aspect of practice that the author mentions that you don’t often hear about is relaxation. The author says “if you aren’t relaxed you’re not going to learn from the practice”, in my experience this could not be anymore true. The practice that you are doing should be relaxing, it should be done without a deadline in an environment where you can break things without consequence.That brings me back to the level of challenge once again, this is because the practice should be done at a difficulty where you can learn but not too difficult that you get frustrated. Having learn how much being relaxed helps in the learning process I intend to use this going forward. The goal is to get to the point where you enjoy your practice sessions if you do not then you should likely change how you are practicing, and if that still fails then it could be because you don’t really enjoy the thing you are practicing.

The other major point that the author hit upon was feedback, this topic has been addressed in other patterns throughout the book and this is because of how important it really is. Yes it is true that practice makes you better, but practicing the wrong this will make you better at the wrong thing. Feedback is important because it makes sure that while you are practicing you are doing things right and developing good habits.

This pattern has reinforced to me the importance of practice, but more than that it’s showed me the importance of CORRECT practice. I plan on implementing this pattern not only throughout my software career, but on any skill that I want to develop in the future.

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

Dig Deeper

Dig deeper is a very important apprenticeship pattern to remember throughout your career and especially one to pay close attention to early on in your career.  It stresses that just writing a solution that you found online or just guessed until it worked is not good enough. It is important to know why the code solved the problem that you were having.  You should also look as to why was this the chosen solution, why code A over code B. This will help you stand out at work as someone who is a more effective problem solver. This will also help so you don’t submit a project that is only half complete; maybe the question that was answered on stack overflow did not include a test that was specific to your work.  If you do not dig deeper into your solution you may not realize this and turn in an unfinished project. When you only scratch the surface and just barely do enough to get by or even less than that work falls to others. There is a set amount of work that needs to be done for each project. Just because you do less doesn’t mean less work needs to be done, it just means that you are putting a bigger burden on the rest of your team that needs to complete their own work and pick up your slack as well.

When moving on from school I intend to make it a point to set aside time to review all the work that I complete as well as try to fully understand other parts of the program that I have a chance to see before submitting my work.  I think this will be beneficial for a few different reasons. First it will help set an impression with both my peers and superiors that I am a thorough worker who puts extra effort into my code. More importantly though it will allow me to expand my knowledge and provide the best possible solution for the problem that I am presented with.  It will help a well rounded tool kit that I may not only use immediately but could be applied in the future too. Doing this early on will create a solid foundation to build on for the foreseeable future.

From the blog CS@Worcester – Tim&#039;s Blog by nbhc24 and used with permission of the author. All other rights reserved by the author.

Expose Your Ignorance

This week I read the section called Expose Your Ignorance. This sections is something i can relate to very well. I am a senior in college and by that time many people would think that you would be able to program thing by yourself.  You should know about at least 2-3 languages by now and have the knowledge to work in the real world however just like the section “White Belt” there are always going to be people better than you and you don’t know everything yet. It is still a learning experience and for me in the class that we are taking now the section we are doing for the project. Which is encryption services is still something I don’t know much about at all. Just saying that you know nothing about something would be better then you hiding and saying nothing. That is what a team is about. To help and encourage each other to do what you can do and that way you can help them when they need help. During hackatons that i go to when meeting new people if we wanna work on a project we all have to introduce ourselves to each other. We also have to tell people what we can and can’t do because if we depend on someone to the most important part of the project and they don’t have the knowledge to do it in the end we would not have a project to present. Also just because you don’t have the knowledge to work on the project you should not just sit around and do nothing. Take this time to learn a new language, download the library’s needed to work on the project, watch videos, and work with a project partner to see if there is anything you can do. Just like the section says people are more inclined to make themselves look competent then just to tell others that you don’t know what you are doing because there are people looking up to you for advice or employers looking to you for the knowledge. That is why this section teaches you that you that lying about knowledge inst worth it and to accept your faults and work on them another day.

From the blog CS@Worcester – The Road of CS by Henry_Tang_blog and used with permission of the author. All other rights reserved by the author.