Category Archives: CS-443

Erockwood Post #5

An important part of software testing is the testing of the software itself. But what if you were able to automate the testing? One of every programmers core ideals is to try to automate as much as possible, because programmers are “lazy”. One framework that allows you to do this is Gradle. Gradle is a build automation tool rooted on JVM, so it is perfect to use with Java. We can use GitLab’s Continuous Integration tool to allow our code to run and test every time it is pushed to GitLab. This is very useful so that any changes made are automatically test each and every time an update is pushed to Main. Once you have your Java project set up, you need to initialize Gradle into the directory of the Java project. After you have done that, you can copy your Java files to the Main src folder in the new Gradle section in the directory. All of your test files will go to the Test src folder. You can then run gradle build to build the project, then gradle test to run all of your tests in the test files using the files in the Main folder.

After this and gradle test outputs successfully, you can set up GitLab’s Integration by using the .gitlab-ci.yml file in your project. After you have added that, all you need to do is use Git to commit and push your project to GitLab and then check the CI/CD tab to watch your tests run.

From the blog CS@Worcester – Erockwood Blog by erockwood and used with permission of the author. All other rights reserved by the author.

Erockwood Post #4

When testing software, it can be useful to have testing objects in place to help test methods and functions to ensure correct output, but without having a real object. This is where the multiple types of test doubles come into play. There are four types of doubles, dummies, fakes, stubs, and mocks. Dummies are objects that are passed around, however never actually used. They are commonly used to fill parameter lists and the like. A fake is an object that actually works, unlike a dummy, however there is usually some kind shortcut taken that does not make them suitable for final production. A stub is used to get a certain answer from a test, and they will not respond to any outside input, only what they are programmed to do. And lastly, we have mocks, which are objects pre-programmed to respond to certain expectations given the input of the calls they receive.

These objects are all very useful when it comes to testing, as they can all help save time when only certain aspects of a program need to be tested, without having to use the full functionality of a particular object. Dummies are nice in that they can help with filling lists and arrays. Fakes are also nice because they allow you to have a part of an object without having to use the full object itself if you want to test only a part of an object. Lastly with mocks, we can use them to get predetermined outputs for certain inputs, which would assist with testing.

From the blog CS@Worcester – Erockwood Blog by erockwood and used with permission of the author. All other rights reserved by the author.

Test Automation

I the world today, everyone is looking for fast solutions and fast technology. The world is expanding rapidly, especially in technology, so many things are being automated to increase how fast things get done. There comes test automation that falls into these categories to make testing faster, and not rely on manual testing which would take much more time. A lot of the manual testing methods people may use such as regression or unit testing manually, is a time waster and is not efficient for people to do constantly when it can be automated. For test automation, the tests are run automatically and the goal of it is to improve the quality of the software in the most efficient way possible. There is a general criteria that needs to be followed in order for a test case to be suitable for automation. These requirements include that the tests are repeatable and there are many factors for this steps. In order for tests to be repeatable, they need to first set up the test by including the data and environment. Then they need to execute the function and the part of the software that is being tested. And lastly once everything is run, the data needs to be cleaned and the environment it was created in. The next criteria is that it needs to be determinant, which means that the output of the test is the same each time with the same input. The last criteria is that it needs to be unopinionated, meaning human judgment and error in that tense cannot be a factor when the tests are run. Now all the different types of automated tests include code analysis, unit testing, integration testing, automated acceptance testing, regression testing, performance test, etc. Overall, automation has made testing a lot more efficient and the process a lot more easier in a way since it saves much more time than having manual tests in many circumstances.

Links:

https://www.testim.io/blog/what-is-test-automation/

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

Code Reviews

Code reviews are one of the most productive components of software testing. What is code review? Code review is the processes of systematically checking a fellow programmer’s code for errors to prevent bugs and identify potential trouble spots such as scalability issues and buffer overflows.

Not only do code reviews save time and money in the development process, it also provides irreplaceable education to junior developers that they would not be able to obtain otherwise. This give an opportunity for Senior developers to demonstrate how to write clean code, identify problems such as memory leaks, and use shortcuts through real world application.

Some insights about code review found through analyses of the process suggest that each reviewer should only be looking at 200 – 400 lines of code per hour, authors should prepare the review with annotations and explanation of the code, and reviews should only last an hour at a time. With 200-400 lines of code reviewed and only 60 minutes at a time for each review ensures that the detection quality and rate stays high. After those marks the quality starts to drop. Annotations and explanations of code makes the author review it himself first, and then sets it up for the reviewer to understand later.

Code reviews can be done in many approaches and do not have to be long drawn out processes unless working on a software that cannot have any errors where someone’s life will depend on it. Some lightweight approaches include pair programming, sending out code through email threads for peers to review, and tool assisted review. Tool assisted review is one of the most useful. In this approach, you use a code review tool that allow the reviews to happen non-locally and asynchronously, with comment and solution tracking, notifications, and more.

Source:

What is code review? (n.d.). Retrieved May 02, 2021, from https://smartbear.com/learn/code-review/what-is-code-review/#:~:text=Code%20Review%2C%20or%20Peer%20Code,like%20few%20other%20practices%20can.

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.

Automation Testing

For the last and final blog for the CS 433 class, I want to focus on an interesting topic that is automation testing. Nowadays, most companies have implemented automated testing environments. It is the best way to increase effectiveness, test coverage, and the execution speed of software testing. Before I get started, what exactly is automation testing? Well, automation testing or Test automation is a software testing technique that performs using various software tools to execute a test case suite. The automation testing software can enter test data into the system and compare expected and actual results with the generated details test reports. There several benefits of using test automation, it is the best way to increase effectiveness and save money. Other factors include manual testing, which is time-consuming, Test automation does not require human intervention and can run automated tests unattended or even overnight, it is reliable in results, improve accuracy, better speed, and lastly, you can test frequently and thoroughly.

Now let us talk about the different types of test cases that use in automation. While researching a few of them once that I found are High-Risk Business test cases, Test cases that are repeatedly executed, Test Cases that are very difficult to perform manually, and finally, Test Cases that are time-consuming. The way automation testing works is using the pyramid strategy which consists of three levels. According to the blog, the base represents unit testing, then the integration/service layer, the next API testing, and finally the GUI test sits at the top of the pyramid. There are many types of automated testing some of which we learned in class, for example, unit testing, black box testing, regression testing, and even data-driven testing. Automated testing is becoming a popular strategy among many companies, I believe that majority of the companies will implement fully on this technology.

https://www.guru99.com/automation-testing.html

https://smartbear.com/learn/automated-testing/what-is-automated-testing/

From the blog Derin's CS Journey by and used with permission of the author. All other rights reserved by the author.

Test Doubles

Unit testing is a form of software testing where part of the software is tested and working. Recently I’ve been introduced to some methods of unit testing where a temporary object is created in place of an existing object in order to perform testing. The term for this is “Test Doubles”, as just like an actor in a movie has a double, doubles are created for objects in the program for the purpose of testing them. I’ve learned about different types of test doubles in my Software Quality and Test Assurance course, and I’d like to examine a few and give a brief explanation about how they work. The names of these test doubles are dummies, stubs, fakes, and mocks.

Dummy objects are made for the purpose of allowing methods to call an argument, and therefore they do not have any implementation themselves. These are used for methods are not actually important for your tests. For example, if you are trying to test a method and have it return something specific, then a dummy method can be created instead of making a method with code that isn’t relevant for the test.

Stubs, similar to dummy objects, are created for the use of testing code without needing to fully develop it. A test class is called to the stub, and the stub returns a value that is controlled. This is useful for scenarios where the result of the test changes depending on what the input is.

These test doubles make testing for code easier. They reduce the need of excessive code and allow for the methods in the test class to simply call the these test doubles instead. Each different test double has its own use depending on the objective you are trying to reach with your testing.

This article and blog provided very useful info regarding what each test double does and demonstrated each type of test double with examples.
https://dzone.com/articles/test-doubles-mockito
https://mokacoding.com/blog/swift-test-doubles/#:~:text=Dummy,the%20behaviour%20you%20are%20testing.

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

Blog Post #5 Static Testing

After working with Checkstyle in the recent activity, I wanted to look more into other static testing tools, but this led to me focusing on the purpose and function of static testing. I had an idea on how it worked prior to the activity, got practice using one of its tools in the activity, but I wanted to read more about static testing in general to get a better grasp on the concept and how it works.

Static testing is based around testing code without actually running the code, as opposed to dynamic testing that checks the code when it runs. The two main static testing techniques are manual examination and automated analysis using tools. Static testing is effective because it can catch early mistakes, takes less time to test, and leads to improved productivity. Checkstyle was the main tool that we worked with, but there are others such as Soot and SourceMeter.

I think the main aspect of static testing that I wanted to learn more about was how it compared to the normal testing that we have been working with, and after working with stubs and mocking in the past activities, it feels similar to mock testing because it seems more about testing behavior than state. It felt like that way to me because JUnit tests can still run when the static test picks up errors if the errors are programmed to be ignored, similar to how a JUnit test may pass but not work properly because it picked up a different method that had the same return type, which is the purpose of behavior testing.

However, with static testing, the proper method can be called and the code could have the right behavior and state, but still not pass because of errors found with the test, such as Checkstyle, which finds errors due to the selected coding style/standard. These errors can also be coded to ignore and still run.

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

https://www.guru99.com/static-dynamic-testing.html

From the blog Jeffery Neal's Blog by jneal44 and used with permission of the author. All other rights reserved by the author.

Static Analysis Tools

For my final blog post for the class, I decided to look at a blog post from Codacy. In this blog post, they talk about how only about 15% of developers use static analysis tools and that more people should. The blog post starts by talking about in the past a lot of developers manually look for errors and bugs within their program and how this method of code analysis is very error-prone because humans are prone to making errors and are likely to miss a bug or two. I hate to admit it but I agree with them on this point. Human beings are flawed and will inevitably make a couple of mistakes. We don’t know when or how but we will. This is just a part of human nature. Computers can run many more tests than we can and very quickly find errors and save a lot of time and money in development. Even though static analysis tools are powerful, we still need to pair with some dynamic testing because static analysis cannot account for every thing that could happen or go wrong.

From the blog CS@Worcester – Just a Guy Passing By by Eric Nguyen and used with permission of the author. All other rights reserved by the author.

Testing Functional Code

In programming, it is essential that developers can ensure that their code works as expected. One way to ensure this is unit testing. However, unit testing and many of the general testing styles are only convenient and simple for basic types of projects. For example, unit tests are great for public libraries made up of classes and functions that can easily be tested. Not only is it easy to test these, but it is simple to understand. You just make objects and call methods and check the results. However, not all code is made up in that fashion.

A clear example of this is a programming language such as my Sea language. In theory, I could take a few weeks and create proper tests for everything involved. However, creating production-level unit tests for a project of this size by yourself is tedious and time consuming, to say the least. One way I find convenient to help test my language is to simply create a sea file with code I want to test the interpretation/transpilation of and then run both the transpiler and interpreter to check the results. Another thing I did was add a debug option to print out the generated tokens, AST, and memory.

This is admittedly janky. There is no standardization for my testing process. Luckily, most of the problems I run into either generate a Python exception, or an obviously incorrect output. That said, maybe that’s only because those kinds of problems are the only ones I find and there are tons of hidden errors that are laying quietly. That overall is one of the best things about Python, and my motivation for Sea. In Python, it is really easy to write thirty lines of code and then run it and have it execute without any errors. This is because the syntax is so simple and readable that its easy to find errors before you even run the code.

Sometimes, I think its alright to not properly commit to testing code. Code that relies more on user input than parameter input (what I’ve called functional code) can be incredibly challenging to properly test. For instance, if I were to properly test Sea, I would need to create sea files that have almost every combination of valid syntax. Not only that, but I’d need combinations of valid and invalid syntax as well to make sure the code finds the errors. The point of testing is to save time and to ensure valid code. In the case of a programming language, I think its easy enough to ensure valid code and in exchange you can save almost half of the total time you’d otherwise need to be spending.

From the blog CS@Worcester – The Introspective Thinker by David MacDonald and used with permission of the author. All other rights reserved by the author.

Starting off Clean

I have a noticeable tendency when I’m coding or even when I’m gaming. After a while of making progress, I often reach a point where I’ve learned enough to remake – whatever it is that I made – much better. So, I’ll get to work on modifying what I currently have in an attempt to improve it. This can work sometimes; usually, however, I end up with a lot of complexity laid out in front of me and I become lost in it. Then, I follow my tendency to simply start over.

In my Sea programming language for instance, I started without any real knowledge of how to make a language. I followed a tutorial with pretty bad code and modified it to serve my needs, learning along the way. I’ve recently added all of the combined assignment operators as well as loops. The next step is to add a method of mimicking main memory so I can add functions and proper variable scopes, as well as memory management. So, I want to start off by refactoring the code I currently have. I made decent progress but then I found myself with numerous files open without any new working code. Since I was rewriting basic features anyway, I finally gave in and started rewriting all of the Python code from scratch. The new code can currently be seen in the overhaul branch, until I finish and merge it. (If you’re reading this in the future, that link might not be useful anymore so try this compare link.)

So, I’d like to discuss the benefits and drawbacks of this habit of mine. First off, sometimes, starting off clean just helps manage the complexity of a problem. Being able to go through every file of code and determining which lines are good is incredibly useful and you can find things you otherwise won’t notice. With git and the ability to copy and paste, it takes hardly any time to reincorporate good code. However, I tend to still think of this process as something I ideally shouldn’t do. Maybe it would save me a lot of time to simply refactor what I need to. It’s possible I just need to get better at refactoring. However, it’s also possible that I’m simply new at a lot of this and in the future I’ll write more solid code from the beginning anyway.

I think, at least in this current Sea overhaul, starting off clean has been nothing but positive for me. This is code I’m very new with and having added so many features, I understand it significantly better than when I first wrote it. I think at the end of the day, both refactoring and starting off from the beginning are valid strategies. As we learn, we’ll learn which to use when. If you only need to make a few changes, then just refactor the code you already have. However, when you’re faced with a massive redesign, just take the time to rewrite it. The problem isn’t so much which you choose to do, but rather when you decide to do one over the other.

From the blog CS@Worcester – The Introspective Thinker by David MacDonald and used with permission of the author. All other rights reserved by the author.