Category Archives: CS-443

Understanding Continuous Integration and Continuous Delivery (CI/CD)

While good testing and version control habits are always helpful and save a lot of time, the process of committing changes, running tests, and deploying the changes can in itself be time consuming. This is especially true in an agile development process, which aims to make small, incremental changes in a series of sprints. Ideally, the process of committing, testing and delivering could be done in a single command.

This is where CI/CD comes in. An Oracle blog post on CI/CD describes the software development pipeline as being a four-step process: commit, build, automated tests, and deploy. CI/CD involves automating this process so that a single commit results in changes deployed to production, so long as the changes can be built and pass the tests. However, any of these stages can be skipped and not all of them have to be automated if it doesn’t make sense to do so. Additionally, other stages can be added if desired.

Oracle stresses the importance of testing in this process, and the requirement to have a suite of unit, integration, and systems tests. These are important to have for any project, but are vital if a commit is automatically deployed to production to make sure users are getting a reliable product.

Gitlab uses Runners to run the jobs defined in a file named “.gitlab-ci.yml”. Jobs can be defined in the stages mentioned above, or any arbitrary number of custom stages, to create a single pipeline. When a commit is made, the pipeline lists the stages and whether they pass. Of course, unit tests should be run before a commit to ensure that the code is behaving as expected, but once a change is committed the rest of pipeline can be automatic.

In large systems, this automation is especially useful. You may be not able to compile an entire code base on a local machine. You may not be working on the same schedule as the rest of your team. Automating other portions of testing and deployment allows a single developer to finish a feature or patch on their own and reliably get it into the hands of users.

In researching software engineering jobs, it seems that many companies use Docker as part of their CI/CD process. Imagine you want to make sure your software runs on Mac and Windows machines. Docker can use predefined images to build isolated containers in which the code can be run. A pipeline can contain separate build stages, for example, to make sure the code builds on both operating systems before running tests and deploying. Next week, I will look at Docker in more detail and describe how it can be applied to software testing.

From the blog CS@Worcester – Inquiries and Queries by ausausdauer and used with permission of the author. All other rights reserved by the author.

Static VS Dynamic Testing


In Software Testing, the two
most popular or important methods for testing are static and dynamic. While both
are obviously named, its good to go over the distinctions, and more importantly,
the actual implementations of both.

           Static
testing involves review of project documents, including source code, to weed
out any actual or potential security flaws and general mistakes. This takes the
form of Informal and Technical Reviews, Inspections, Walkthroughs, and more. This
process can involve an inspection tool or be performed manually, searching
for potential run-time problems, but not actually running the code. Dynamic testing
conversely involves actually executing code looking for functionality,
resource usage, and performance. We have been using dynamic testing, specifically
unit testing, in our class so far. Dynamic testing is used mainly to verify the
program runs in accordance with the specifications outlined for it, specifically
called System Testing.

           Of
course, both have their own advantages and disadvantages. In static testing you
have the potential to find bugs that may have made later development more
troublesome early in the process, which can save lots of time and frustration in
the future. However, there may exist some flaw that only a running program can
reveal, but it only in the code that is executed. It would seem to me, that
these should not be exclusive and in fact, they have a logical order.

           You
would begin with static testing, like proofreading a paper, searching for misspelled
words (poor variable/method names), run on sentences (needless complexity or
repetition), and reorganizing to best get your point across (logical order of
declarations/methods, documentation). Like writing a paper, it is best to do
this ahead of run-time (reading through), that way you don’t have to constantly
stop to bandage small errors. In the same way it seems essential to ‘proof-read’
your code before execution to make sure it is free from identifiable errors
before you move on to seeking out run-time errors. You wouldn’t want to have to
fix both at the same time like with proof-reading.

           In sum,
these two could be grouped as pro-active or reactive, static and dynamic respectively,
and best explain their use. As mentioned, these also make sense to utilize in a
specific order, ensuring code is as correct as possible upon inspection, then
running it to see where flaws undetectable in a static environment have arisen.
These together ensure quality software that is optimized and secure.

Static Testing vs Dynamic Testing: What’s the Difference?
Static Testing vs. Dynamic Testing

From the blog CS@Worcester – Press Here for Worms by wurmpress and used with permission of the author. All other rights reserved by the author.

The Start of Unit Tests

I decided to read a post called “Getting started with Unit Tests” by Miguel Hernandez which talks about how a developer should begin working with unit tests and why its important in developing code. Miguel talks about how making tests and designing tests help developers understand the code that they have written and how to be efficient with your code so that changes do not break your code later on. The post also talks about how you should try to keep your tests simple and focus on one thing rather than multiple things at once. This post made me think about how testing is an extremely important tool because even if you don’t know where to start when you are coding a project you can start with the test cases and figure out what needs to result and then code your project to fit those requirements. I think the way the article put it was spot on when he said ” Many developers think that Unit Testing is like flossing. Everybody knows it’s good, but many don’t do it. ” because that is the outlook I’ve had on the topic so far in my previous coding experiences. Something that I want to work on is keeping my Unit tests simple and not trying to create complex tests.

Link to Article/Post referenced: http://eventbrite.com/engineering/getting-started-unit-tests/

From the blog CS@Worcester – Tyler Quist’s CS Blog by Tyler Quist and used with permission of the author. All other rights reserved by the author.

Testing Rant

Testing is a huge part of writing any piece of code from simple assertion testing to multi-platform testing. JUnit 5 or JUnit Jupiter is now available for testing on most IDEs. JUnit Jupiter is an incredible new testing platform. The beauty about using JUnit 5 is there is backwards compatibly for previous tests you have written in JUnit 4 or others. By others, I mean any third-party testing because JUnit Jupiter also allows for that. But enough about the benefits of JUnit Jupiter, why test in general? Most people that write anything knows testing is vital for running the program but there are also other benefits often over looked. By constantly testing you are able to see run-times in the code which can then be further inspected to be improved upon. If a part of your code was causing a long delay in testing it would be easy to find and debug or re-write into a more efficient piece of code. This in turn means that testing also helps with the design process. You will want the code designed to be as efficient as possible and the best way to do so is also testing. When bringing testing on a bigger level, it can save companies lots of money from stopping them from missing potentially fatal bugs in their system or vulnerabilities. When it comes to testing there really is only benefits, and that is why you should always be testing!

From the blog CS@Worcester – Journey Through Technology by krothermich and used with permission of the author. All other rights reserved by the author.

Test-Driven Development (TDD)

Writing software is fun. Mostly.

When I look back on the projects I’ve made, a couple big ones stick out which were mostly not fun. For example, I made the mistake of trying to build an Android app before I fully understood what a class is. Design patterns were not even something I had considered. The consequence was a fairly simple app with code that was supremely complicated and confusing.

For my next project, I tried to do better with the lessons I had learned. I continuously had errors that I didn’t understand; errors that were seemingly unrelated to the changes I had made. After a couple weeks of struggle I deleted all my files and uninstalled Android Studio. The frustration was so bad it made me want to quit programming. The frustration could have been prevented.

This is where tests, and specifically Test-Driven Development (TDD) could have saved me.

James Grenning has a blog post discussing how he feels about TDD, after years of writing software without it. TDD forces you to think through what you want your code to do. If you can’t test your code it’s likely a sign of bad design, so TDD indirectly leads to a better software architecture. Tests describe what the code is supposed to do, and the tests will always be there. If the code stops doing it in the future the tests will fail, acting as a permanent, enforced documentation. This leads Grenning to bring up the concept of regression tests, which confirm that your new changes don’t modify legacy behavior. The suite of regression tests that you slowly build over time will make sure nothing is inadvertently broken. But as you write new tests, you’re also getting instant feedback that your new code is performing to specification.

My life as a programmer is much better with TDD.

James Grenning

TDD brings you back to the programming exercises you did when you first started learning. It is satisfying as it is to struggle through a problem and make your project do what you want. But it is so much more satisfying to see a big green bar that tells you everything is working, including everything you’ve done since the beginning of the project. Then you can play with your new features manually if you so desire.

There are some downsides to TDD. More code means more time and more to maintain. Sometimes you’ll have to change tests because what your code is doing also changes. Furthermore, TDD is an art in itself and must be learned, meaning you may need to break old habits of bad design to write code that is testable. I’m inclined to agree with Grenning that debugging a complex system is much more time consuming that these downsides.

It only took a couple weeks of clear thinking to realize I had overreacted when I uninstalled Android Studio. I learned to have a lot more patience and take the time to do things the proper way. I still forgo testing and TDD for small, personal projects, but the benefits of TDD greatly outweigh the downsides for any important project.

From the blog CS@Worcester – Inquiries and Queries by ausausdauer and used with permission of the author. All other rights reserved by the author.

Is That Bug Bothering You

Using Black Box Testing To Your Advantage

Blackbox testing is a strategy programmers use to test code at the level of the user. They have no access to the source code and only see what a user would see. The goal is to see that everything functions correctly from the view of the user. This type of testing doesn’t require much knowledge of the structure of the program and could be executed without any access to that information. 

Blackbox testing can be problematic because you  can’t see what part of the code is problematic when running into an error. However, if you have code that is functioning properly, perhaps blackbox testing can be quite beneficial. In a scenario where you have complicated code keep in mind the YAGNI rule (You ain’t gonna need it). Perhaps  all bugs aren’t worth testing for, if the user couldn’t trigger the bug then why go through the testing trouble. Yes it is always better to safeguard code against any error but if fixing this hidden bug would over complicate things then just let it be. Blackbox testing comes into play here, if you are not running into errors as the user then consider whether or not you need to safeguard any code level concerns. An article from qablog.practitest.com states, “When we test, the idea is not to find all the issues, we only need to focus on those issues that will affect our users.

The question of “If a tree falls on an empty forest, does it make a sound?” is simple in the context of testing…  If there is a bug that no one will run into, then we do not care about this bug!. Spending time and resources on patching spots of code that aren’t going to be disrupted by a user is a quality issue. Check out this article for more information on this idea.

https://qablog.practitest.com/you-do-not-need-to-make-the-wrong-assumptions-about-your-users-anymore/

Do not make the wrong assumptions. (2019, September 15). Retrieved from https://qablog.practitest.com/you-do-not-need-to-make-the-wrong-assumptions-about-your-users-anymore/

From the blog cs@worcester – Zac's Blog by zloureiro and used with permission of the author. All other rights reserved by the author.

Software Quality-Quantity Trade-off

Programming was extremely hard for me at first. Once I discovered that programming isn’t just typing code, I spent so much time worrying about getting the perfect design, imagining what could go wrong, and researching alternatives that I rarely actually coded anything, at least for a brief period. While this concern may have taught me a lot in my research, I know better now. There’s a trade-off between time spent designing and time actually making software work.

Likewise, there is a trade-off between creating high-quality software and adding more valuable features, as Martin Fowler discusses in this blog post. Fowler is a software developer and author who has written extensively on the topic of software quality and design. In this blog post, he poses the question “is high quality software worth the cost?”.

Short answer: yes it is. To go further, Fowler believes that the question really doesn’t apply to software because high quality software is cheaper. He also makes the distinction between internal and external quality in software. For example, users notice a quality user interface, but have no idea which design patterns were used.

Internal quality is the goal of quality assurance and testing, and while it isn’t directly visible to the user, it makes it so much easier to provide a user with additional features by adding to an existing code base. In my last post, I wrote about SOLID and a podcast by Coding Blocks. They discussed how good patterns take a lot more code to write in the beginning, because things are broken up into smaller classes, with more, smaller methods. But as Fowler describes, the initial work more than pays off in the long run when code is easy to read and understand.

Anyone who has learned to program has spent hours looking for a mistake on a small project. These get harder to find as a project grows, especially when there are hidden dependencies among poorly-formatted code. Now imagine you wrote the code 2 years ago. And you can’t even fix it because you’re on vacation, but it’s preventing users from accessing their accounts so your coworker has to. Quality code and tests will drastically improve the chances that the problem is quickly patched and your users are happy. Take it one step further: this problem could have prevented entirely with sufficient testing and more focus on quality.

Most time is spent reading code rather than writing it. Fowler mentions this, but it is also an important theme in Clean Code by Robert C. Martin [1]. If you write quality code now, you can write even more quality code in the future.

[1] Martin, Robert C., et al. Clean Code: a Handbook of Agile Software Craftsmanship. Prentice Hall, 2016.

From the blog CS@Worcester – Inquiries and Queries by ausausdauer and used with permission of the author. All other rights reserved by the author.

Software Quality Assurance Introduction

Hello again everyone, I am taking Software Quality Assurance class and once again, I will be using this blog to summarize about what I’ve learned through articles and podcast throughout the semester. I’ve been doing internship the whole summer about software quality assurance on both UI and unit testing and I learned a lot from it, and now hopefully, this class will help me expand those knowledge even further on this area.

From the blog #Khoa'sCSBlog by and used with permission of the author. All other rights reserved by the author.

We Are Back CS Gang

Hello again to all of my few viewers that read my blog. I am back, but this time it is for a brand new class. CS-443 (400 Level, getting to the good stuff now.) Once again, I will be summarizing, reviewing, and commenting on articles, podcasts, and other things that relate to what I am studying in this course. Looking forward to getting my reviews back out there after a nice 6 month hiatus.

From the blog CS@Worcester – My Life in Comp Sci by Tyler Rego and used with permission of the author. All other rights reserved by the author.

Software Quality Assurance & Testing

This fall semester I am taking a course on Software Quality Assurance & Testing and I will be using this blog to write about new topics I explore in this area as part of this class. I have been looking forward to taking this class all summer and learning more about software development!

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