Category Archives: Week 8

Test Automation vs. Automated Testing: the difference matters

More companies are gravitating towards practicing continuous development. When it comes to a DevOps and delivery model where software is constantly being developed, it is important to know that there’s is a difference  between test automation and automated testing.  Automated testing is the act of conducting tests via automation as opposed to doing them manually. Test automation is automating the process of tracking and managing different test. in this article, Kyle McMeekin explains how test automation is a huge when it comes to continuous testing.

If something stalls or break down during the development pipeline, this can drastically delay the delivery of the following releases. This is a roadblock in a continuous testing environment because speed and consistency is imperative to support a continuous testing model as McMeekin describes. Test automation eases the burden of tracking which environments have deployed new code, when each piece needs testing and how those requirements integrate back into the moving process of continuously delivering software; it does all that through automation leave more time for testers. The extra time can be focused on creating effective test cases to ensure the quality of the software since they’re no longer bogged down in managing all the minutia of testing needs. Continuous development and DevOps are becoming the norm and so will continuous testing. with the help of test automation, managing the changes that comes with injecting testing throughout the entire development pipeline can much easier.

https://www.qasymphony.com/blog/test-automation-automated-testing/

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

11/6/2017 — Assignment 8 blog post Week 8 Cs 343

https://addyosmani.com/blog/decorator-pattern/
Design patterns are important for building software. It is equally important to know about for core Java interviews. So, it is always good to have a clear understanding of the various design patterns in Java. The decorator design pattern is a prominent core Java design pattern. In addition, it is used in JDK in IO packages. In the IO package it has the decorated Reader and Writer classes for various settings such as for BufferedReader and BufferedWriter. This blog post examines the decorator design pattern.

The decorator design pattern is used to extend or modify the behavior of an instance at runtime. While inheritance is an extension of class methods, for the decorator design pattern you can choose any single object of a class and modify its behaviour, leaving the other instances unmodified.

The article discusses the decorator pattern as being implemented by constructing a wrapper around an object. This is done by extending its behavior. In the decorator design pattern, you start with an interface. This becomes a blueprint for the class that will contain decorators, which can now contain basic functionalities. The decorator design pattern contains an abstract class which contains the aggregate relationship an attribute type of the interface. The constructor of the class assigns the interface instance to the attribute, which becomes the decorator base class. This class can be extended to contain as many concrete decorator classes with its own methods. Finally, the article gives examples of the implementation of the decorator design pattern as an ice-cream with decorative toppings. For the design pattern you have the basic ice-cream and as much toppings as you would like. So, you have ice-cream as an interface. Simple ice-cream and ice-cream decorators as classes and their inheritance are as much toppings as the developer would like.

I chose this post because it is always important to learn more design patterns. Design patterns helps to organize the code and it helps to make instantiations more efficient. In the case of the decorator design pattern the advantages is that it is more flexible than inheritance. The decorator method provides a more flexible alternative to subclassing for functionality and method extensions. The reason for this is that inheritance adds responsibilities at compile time and run-time. Another advantage is that it allows behaviors to be modified at runtime. This means that the behavior can be modified without going back to the existing code and modifying it. In addition, the decorator method provides a solution to permutation issues since components are wrapped by a number of decorators. Altogether, the decorator design pattern adheres to the principle that I have seen in all of the other design pattern thus far and is my most favorite principle in software engineering that is the principle of being open for extension but closed for modifications. So, I chose this blog post to learn more about design patterns in order to extend my knowledge and to incorporate in my own program for code organizations and efficiency. The decorator design pattern is used in the prominent core Java design pattern. It comes up often in core Java interviews. So, this is a design pattern that is important to learn about.

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

11/6/2017 — Assignment 8 blog post Week 8 Cs 443

https://blog.asana.com/2016/12/7-ways-to-uplevel-your-code-review-skills/
Code review is always my least favorite part of software engineering. Becoming one doesn’t come easy. So, this week we discuss 7 aspects that can help to improve coding review skills. The first is to prioritize the goals of code reviews with the team. It is suggested that all members should know about the primary goals of the project. So, a team should set up a time to meet to discuss the primary goals. The writer’s favorite part of code reviews are the following:
To help learn to negotiate with co-workers, to think like them and adapt to similar coding convention so that the writer can easily navigate and change the code.
To spread knowledge about files and features, and what has changed recently, in case there is a bug in the code, 2 people can help in diagnosing and fixing the problem. No one should have one view of their own code.
The writer’s least favorite part of code review are the following:
Catching bugs. Automated tests and using apps are good ways to see how code actually runs.
Enforcing basic style rules.
My most favorite part of code reviews are the sharing of knowledge and codes with team members. Code sharing allows for a broader view to help improve coding skills. My least favorite part is catching and debugging bugs.
The second recommendation to improve code review skills are to run the app and try playing with the features. Reading code is not the same as interacting with the code and it is unlikely that a programmer will catch most of the bugs from reading codes. Finding bugs through reading takes years of practice. It is better to run tests on the code and to interact with it rather than using your head. Chances are you will catch important cases that would have otherwise be missed.
The third method is visualizing method call hierarchies. This involves drawing and visualizing which methods call which other methods or which objects use which other objects. The key is to quiz yourself. Plain reading is not as effective as committing it to memory and writing it down.
The fourth way to improve code review skills is to do the code reviews as soon as you see the request. Even in large reviews, coders should try to make the first pass as soon as possible. However, code reviews are not always an easy task to do immediately. There may be barriers such as the code has been changed many times. Below are some tips to help speed along the progress:
Set a time limit, about half an hour. Spend the hour mapping out the changes and writing down questions. If not ready, then schedule and commit to a time when you can make more detailed pass and approve or request changes.
The final tip which I thought was very helpful and important when designing software is to keep 2 separate repositories on the machine, one for your own changes and one for changes you are reviewing. This allows your changes to stay in place so that compiling changes made by co-workers won’t destroy it.
I chose this blog post to compare it with my own experiences with software development and code reviews. I agree with the final comment about having 2 separate repositories as it would be easier to recover back files of packages that might have been disrupted by changes with other co-workers or with changes you made yourself.

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

The Observer Pattern

Today I will be talking about a design pattern known as the observer pattern. In a blog put out by the website javapapers.com, the observer pattern is used when multiple objects depend on the state of one object. For example, Class A and Class B rely on the state of Class C and Class D to run. If Class C is in state 0 and Class D is in state 1, Class A will execute and Class B will not. If Class C is in state 1 and Class D is in state 0, Class B will execute and Class A will not. Class A and Class B need to be aware of the state of Class C constantly, and need to know when there is a change in the state of Class C. We can use do this by using observers for Class A and Class B. However, java does not support multiple inheritances; that being a class can’t inherit from more than one parent class. We can use the observer pattern to create observers for objects, which will help objects be aware of the state of different objects.

 

The blog uses an example using the relationship between a blog and a subscriber. The blog user subscribes to a blog for updates. When a new blog is added, users will be notified of the new blog. In this case, the user is the observer. The UML diagram for this example points out that a subject can have many subscribers. Both the subscribers and the users have implementation classes, which notify the classes of each other’s states. The implementation classes are “observers” in the UML diagram. The subject implementation observer gets and sets the state of the subject, while the user implementation observer updates to see if there are any new changes to the state of subject.

 

I selected this article to expand on my knowledge of software design patterns. I think they are useful tools to have, and each one has its ideal uses. The observer pattern is good for classes that are related and depend on each others states to function. I learned how I can implement observers for objects for these types of relationships. Now, instead of having the object looking for updates constantly working to search for updates, the observer will do it for them. This leaves the object totally out of the loop, and is only notified when the observer finds a change in state. I hope to implement this pattern in my future projects, as I think it is a great way to keep code efficient, neat, and organized.

 

Here’s the Link: http://javapapers.com/design-patterns/observer-design-pattern/

 

From the blog CS@Worcester – The Average CS Student by Nathan Posterro and used with permission of the author. All other rights reserved by the author.

Web Apps vs. Native Apps

With our discussions in class about typescript and java script for use with Web-apps, I believe it is important to discuss the difference between web-apps and native apps and how our knowledge of them can help us decide which one is more preferable. I choose this article by Lifewire because it provides a great compare and contrast of web-apps and native apps.

There has been an ongoing debate over what type of app is better – Web Apps or Native apps. Firstly, I think it is important to distinguish the two. Typically, a native app is an app that is used local on a device. These apps are usually downloaded and installed on the device. For example, the camera app on an android phone or Microsoft word on a desktop computer. While native apps are usually local on a device, Web Apps are apps that are not installed locally on a device.

Let’s take for instance a locally installed app. That app can access almost all of the devices features (if permissions are granted). Snapchat, for example, is an instant messaging app using a smart-device’s internal camera. That is a native app using another native app. A web app only has access to a limited number of the device’s native features. This may seem like a bad thing, however, there are greater benefits to web-apps than you may think

The great thing about native apps is that since they operate specifically on software designed for a particular device, it can be greatly optimized and catered towards that device, thus enhancing the users experience. At the same time, this means whenever a native app needs to be updated, the device needs to keep downloading updates and bug fixes. With a web app, all updates are handled on the back-end, therefore no native changes or downloads need to be made.

Both web-apps and native apps are used everyday, and arguably, they can both be used hand in hand. Web apps can be developed for native apps and native apps can be developed for web apps. Paypal has a web-app in browser, however they also have a native app that can be downloaded and updated. I think as technology progresses, we will see more web-apps as cloud computing seems to be the future. Knowing this, I personally think that web-apps will continue to evolve because they require no user action to update and they do not need to be designed for a specific system, therefore making

 

Source: (https://www.lifewire.com/native-apps-vs-web-apps-2373133)

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

Alpha vs Beta Testing

For this week’s blog I chose the article titled “Alpha Testing vs Beta Testing.” I chose this article because it covers two types of testing I haven’t read too much about. I also like the comparison type so I can see different situations why I might choose one over the other.

To start, alpha testing is a type of acceptance testing. It’s used to identify all the possible issues in a product before it gets released to users. The idea of this type of testing is to simulate real users by using blackbox and whitebox methods. The article mentions this type of testing is usually done by internal employees in a lab type environment. The overall goal is perform tasks that the typical user will be doing frequently. This testing is done near the end of the software development cycle but before beta testing if beta testing is being done.

Beta Testing is another form of acceptance testing done by real users in a real environment. It’s mainly used to gather feedback and limit product risks before the product gets released to anyone and not just a small testing group. This would be the last type of testing before a final product gets shipped to customers.

While beta testing and alpha testing share some similarities there are some key differences. The first being that in beta testing reliability, security, and robustness are checked which is not true for alpha testing. Another difference is how issues are addressed. For alpha testing it’s not uncommon to make code changes before an official release. With beta testing code changes will usually be planned for future versions after the product is released.  Lastly, with beta testing you are getting feedback from real users and this will usually be a more accurate analysis of how a product will perform over alpha testing.

For larger product firms, a product release will usually incorporate both alpha and beta testing. Below is a typical flow chart of the process.

alpha.png

To clarify, the pre alpha phase would be a prototype where not all features have been completed and the software has not been officially published. The release candidate phase is when any bug fixes are small feedback based changes have been made.

In conclusion, this article was really great comparing alpha and beta testing. It goes into more details with some advantages and disadvantages of the two as well as some entry and exit criteria however this goes beyond the scope of this blog. After reading about these two types of testing I would definitely want to include both in a product release strategy however I would choose beta testing if I could only choose one. I think real user feedback in a real time and natural environment is most valuable before releasing. At the same time it would be easy to argue that terrible feedback in a beta testing cycle could be prevented with prior alpha testing.

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

Pipe and Filter Architecture

For this week’s blog I chose an article on the pipe and filter architecture appropriately titled “Pipe-And-Filter.” I chose this article after googling what some of the most common software architectures are and learning that pipe and filter was commonly implemented. This article seemed like a good length with straightforward information and diagrams to help with understanding the material so that is what I chose it.

To begin, this architecture consists of any number of components referred to as filters due to the fact that they filter data before passing it through connectors called pipes to other components. All of the filters work at the same time and this is usually implemented in simpler sequences although is not limited to that.

pipe1

Above is a simple diagram to show how the architecture flows. It’s important to know that filters can transform the input data from any number of pipes. The pipes pass data between filters however it is unidirectional implemented by a buffer until the downstream filter can process it. The pump is where the data originates such as a text file or I/O device. Lastly the sink is the end target of the transformed data such as a file, database, or output to a screen.

One good example of this architecture would be a Unix program. One program’s output can piped into another program’s input.

pipe2

Above is a more complex diagram to show how pipe and filter can start to become complex. Different sources or pumps can interconnect data into their respective streams. An application that uses this architecture will typically link all the components together and then spawn a thread for each filter to run in.

One interesting functionality of this pattern is a recursive filter technique. This is implemented by having a filter inside of another filter.

One common issue with this type of architecture concerns what kind of data types are allowed in a certain pipe. If only one type is allowed, filters need to parse for this which can slow an application down. You may also limit yourself to what pipes can connect to which filters.

After reading this article I have a good idea of pipe and filters main concepts. One thing I wished the article had discussed more in detail would be specific implementations of this architecture. I can’t directly see how I would need to use these concepts in any of the coding I’ve done so far. I can see a general use for this model for an application that takes in a lot of raw data and needs to output it in a useful format for making business decisions. In summary this was a well written article but I need to do some further reading on implementation examples.

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

Common Code Smells

https://8thlight.com/blog/georgina-mcfadyen/2017/01/19/common-code-smells.html

This blog describes some of the most common code smells. A code smell is “a surface indication that usually corresponds to a deeper problem in the system.” Being able to catch code smells early will make it easier to refactor into code that is more extendable, readable, and supportable.

Long Methods

Having long methods makes your code harder to maintain and debug. It will also be more difficult to read as you have to keep a lot of complex logic in mind while reading a long method. Ideally, a method should not have more than one responsibility.

Refuse Bequest

Inheritance is not always the best model to use. If inherited methods go unused or are overridden to do nothing, it could be a sign of this code smell. Inheritance should only be used when a class needs to reuse code from its superclass.

Data Clumps

If multiple methods take the same type of parameters, it’s a sign that those parameters are probably related. The parameters can be combined together in a class to keep them together, which will help keep the code organized.

For example, instead of having a method with three parameters:

connect(String host, int port, String username);

They can be combined in a class so that a reference to the class object is all that has to be passed into the parameter list:

class DatabaseCredentials{
 ...
   public String getHost(){
     return host;
   }
   public int getPort(){
     return port;
   }
   public String getUsername(){
     return username;
   }
}
...
connect(DatabaseCredentials databaseCredentials);

Duplicate Code

This is the same idea as the Don’t Repeat Yourself design principle. Duplicate code is unnecessary and will create similar bugs in different parts of code.

Middle Man

If a class exists just to delegate to another class, you should ask yourself if it is really necessary. If a class doesn’t justify its existence, it should be removed.

Primitive Obsession

Primitive types give little domain context and are not always clear. Where primitives have a domain meaning, it is a good idea to wrap them in a small class to represent the idea.

Comments

Comments provide little value when they reiterate what can be read by a developer, especially if they have not been updated and no longer reflect the current code. Before adding a comment to clarify a piece of code, try to refactor the code so that the comment is no longer needed.

I chose this blog post because code smells are another topic on the concept map. They are similar to design principles and anti-patterns because being aware of them will make sure that good coding practices are being followed. Like the design principles and anti-patterns, I will be applying what I’ve learned to my future code. The more of these blogs I read the better understanding I have of how object-oriented code should be structured, which is one of the important learning outcomes of this class.

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

How to Effectively Discuss Software Testing

It is not easy to come up with a definition that truly encompasses all that the discipline of software testing entails. From writing test cases to performing automated testing, what a particular software tester does can vary greatly. It is not surprising then, that there often misconceptions surrounding discussions of software testing. Reading a post titled “Six Things That Go Wrong With Discussions About Testing” by James Bach on his blog gave me insight into some of the things that I should avoid when talking about testing.

The first point that Bach brings up is that the number of test cases that you have written does not matter. To anyone who has ever written a test case, this is a pretty obvious one. You could write a million test cases that all do the same thing, but if you’re not exercising the code in unique and possibly unexpected way, then you are wasting your time. Any tester who brags about the number of test cases that he or she has written is clearly missing some critical understanding of the purpose of testing software.

Secondly, Bach states that each test should be thought of as an event rather than as an object. Whether it is done automatically or manually, tests must be performed, they do not simply exist. This is why software testers will never be replaced by computers or algorithms. Each time a tester performs a test, it produces a unique and meaningful result. This ties in with Bach’s fourth point, which is that even in the case of automated testing, humans are responsible for the successes or failures of the tests being run. Computers are unable to think critically about problems like humans can, and they can only go so far as to check simple facts, not effectively test software.

Backtracking to Bach’s third point, testers should always be able to describe their testing strategy, even as it evolves over the course of testing. Understanding how and why a given test is being performed allows testers to think about things such as how to improve the test, what tests need to be developed next, and how to develop better tests more quickly in the future.

The fifth topic that Bach discusses is how people “talk as if there is only one kind of test coverage”. As a student currently learning about the types of testing coverage, this one came as a bit of a surprise to me. I imagine that testers who fall victim to this fallacy of testing never received formal education in software testing or have become so set in a single way of testing that they are failing to see the bigger picture.

Lastly, Bach discusses testing as an exploratory learning task rather than as some scripted, monotonous procedure. Again, I think that my current enrollment in a software testing course leaves me a bit biased on this point. Nearly every test that I write is a learning experience for me, and I certainly do not feel that testing is a static task.

While I can certainly see where Bach is coming from with all six of his “Things That Go Wrong With Discussions About Testing,” I am pleased to know that the my understanding of software testing does not fall into any of his categories for the most part. I feel that many of these things apply to testers who may have been self-taught or had minimal theoretical training. I think that my education certainly helps me to see the big picture of why software testing is so essential, rather than just going through the motions of writing test cases for the sake of it.

From the blog CS@Worcester – ~/GeorgeMatthew/etc by gmatthew and used with permission of the author. All other rights reserved by the author.

Practical Uses for Design Patterns

Sometimes completing assignments can become monotonous. I think that I find this mainly happens when I cannot seem to think of a practical use for what I am currently working on. While I understand that many of the example implementations of design patterns are intentionally left abstract so as to highlight the importance of the pattern rather than the complexities of the underlying system, this bores me. My approach to programming is often utilitarian in the sense that I want to know how what I am currently working on is going to make someone’s life easier.

(Image source: https://drquicklook.com/products/usb-to-sd-card-adapter)

This week I listened to Episode 30 of the Coding Blocks podcast, from July 26, 2015. In the episode, Allen, Joe, and Michael discuss the Adapter, Facade, and Memento design patterns. The first pattern that was discussed was the Adapter pattern. I paid particularly close attention to this pattern, as I will be researching and compiling an informative piece on the Adapter pattern in the coming weeks. The podcast provided a link to an excellent tutorial on TutorialsPoint, which I will most definitely be using as a reference for my project research. The real-life example used to describe the Adapter design pattern was that of the SD-card adapter, which takes the SD card and adapts, through the use of an interface, to a USB cable that the computer can recognize and use. The Adapter design pattern implemented in software provides a very similar function by taking two otherwise incompatible interfaces and acting as a bridge between them so that they may seamlessly interact with one another.

In the discussion of the Facade design pattern, I saw some parallels to the Adapter pattern but there were certainly also observable differences. The Facade patterns aims to hide the complexities of some underlying system by providing a simplified interface through which the user can gain access and use the resources provided by the system. The example that the three discuss that I found very interesting was transactional payment processing systems such as PayPal. The goal of applying Facade in this case would be to hide multiple repeated calls to APIs that must be completed each time a user would like to perform a task such as setting up a secure connection, passing a token, storing a token, etc. before actually accomplishing the desired task.

The final pattern that is discussed is the Memento design pattern. While the three seem to have mixed feelings about the usefulness of the Memento pattern, I thought that the discussions regarding Megaman and System Restore’s implementation of this pattern were extremely useful and interesting examples. The pattern, in a basic sense, aims to save a complete copy of the state of the object at any given time. This state object is accessed and maintained by two classes – a caretaker and an originator.

What I like most about the examples and explanations that the three give for their respective design patterns is how practical they seem. While the ultimate goal of applying a design pattern to a particular problem is to simplify the overall implementation, it is certainly not always a simple task to apply a pattern. Understanding some of the motivation behind why applying the design patterns makes an implementation cleaner and more effective satisfies my utilitarian inclinations. I am looking forward to exploring the complexities of the Adapter pattern more thoroughly in the near future.

From the blog CS@Worcester – ~/GeorgeMatthew/etc by gmatthew and used with permission of the author. All other rights reserved by the author.