Testing, Testing and some more Testing

In my Testing class we are constantly learning some new techniques and ways to test software, although there is some hands on testing on actual code a lot of it is more theoretical or to be more specific it is describing how we can test. It is all useful I know it but as a CS major I do want to write code if possible, less theory please, more practice. End of rant? Maybe for now.

This week was about Define-Use Testing. It is somewhat simple concept and I am glad that I can learn about it. It showed us some of the ways that today’s compilers work and make comparisons to display errors in the code. The whole concept of Define-Use testing is all about visual inspection and checking of the code. This will be some useful information for certain aspects of Computer Science field.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

TypeScript, a better version of JavaScript

TypeScript, is it really a better
version of JavaScript? If you are like me and you never used JavaScript before
and then were told that TypeScript is better you will probably have the same
reaction, “OK, so what?”. Well it turns out it is a very useful thing, it is a wrapped
version of JavaScript that will pay attention to the types of variables used
and so on, hence the name. In my search for some answers I have stumbled upon THIS blog by Valentino
Gagliardi named TypeScript Tutorial For Beginners: The Missing Guide (2019).
Like it says it is a whole tutorial, but it also explains in some simpler words
what TypeScript is and why it is useful with a lot of examples. I will go through
it and then look for some more. What helped me right away was Valentino’s explanation
of what is TypeScript: “The definition from the official website says: “a typed
superset of JavaScript” but it assumes you know what a “superset” is and what
“typed” means. Instead to keep things simple you can think of TypeScript as of
“a layer on top” of JavaScript.”

Most of the blog is what it is
supposed to be, a Tutorial, and in my opinion it does it in a very good way, he
starts in an easy way to show certain things, even when somethings is not right
away understandable Valentino comes back to it later and explains in more
detail, what is a plus for me as well is that he does in somewhat humorous way
and that makes the whole learning a more easy going process. Having those kinds
of Tutorials is very helpful for me because knowledge can be learned but what
needs to happen is also the understanding of when and where to apply said knowledge
and with this blog post I’m starting to understand that about TypeScript.

Learning in school about best tools to perform today’s jobs and being able to see it in action before I am thrown into the deep end is a huge plus for me and it should be for everybody else as well. I am always very grateful for the opportunities like this one. I have found out that the TypeScript is used at my work in other departments which tells me it is a good thing to learn and maybe use to further my career. I cannot wait to start writing some more advanced programs in this format, but everything needs to be done slowly, you must learn to walk before you can run and I do intend to be able to run eventually.

From the blog #CS@Worcester – Pawel’s CS Experience by Pawel Stypulkowski and used with permission of the author. All other rights reserved by the author.

REST – INSOMNIA(c)

This week let’s take another peek at the FoodKeeper API. We’ll review the endpoints and how to submit a request to retrieve data. Before we jump into this you need to download and install a REST client. I highly recommend Insomnia, the app not the sleep disorder, (download it here) I’ll wait… Now that you have Insomnia installed let’s talk about endpoints. Last week we covered the four primary HTTP verbs used with REST. Did you have a chance to visit https://www.restapitutorial.com despite the name of the website these aren’t tutorials on how to make REST calls but more like development guidelines for developers writing REST API’s.

So why did I recommend it? Because understanding how a good RESTful API is designed will make it easier to craft your REST calls. So the 4 basic HTTP verbs (POST, GET, PUT and DELETE) are CRUD (Create, Read, Update, Delete) operations. · POST = Create · GET = Read · PUT = Update · DELETE = Delete Kind of makes sense, right? These also make up the endpoints you access with your REST client. In JAVA we add an annotation to the class and the getter and setter methods to define the endpoint. For the FoodKeeper API we are using the Spring Framework (https://spring.io/) to help setup the Rest components. After all the imports are declared the class must be annotated with @RestController so that the compiler knows how to process it. Each endpoint must be annotated to reflect what it does. A POST endpoint would be annotated like this: @PostMapping(“/list/new”) The part in parenthesis indicates the URL path that you would pass as part of the REST Client call and is the actual endpoint. Let’s look at an online example. In a new tab on your browser go to: http://dummy.restapiexample.com/ The site lists 5 public endpoints you can practice against: · GET /employee · GET /employee/{id} · POST /create · PUT /update/{id} · DELETE /delete/{id} Note the curly braces with id in between them – this indicates that you will be passing a value.
Open your REST client, in Insomnia you would type in the URL in the White field in the top center of the screen and select the REST Method to the left of it: Click the Send button and watch the Right hand column you will see it populate with employees. This is the first entry in the list that was returned for me: Play around and get familiar with your REST Client and hit some of the other endpoints at

http://dummy.restapiexample.com/ TIP: For the endpoints above with {id} just append the url string with a number like this: http://dummy.restapiexample.com/api/v1/employees/6821 All right go play and learn something! #CS@Worcester #CS448

From the blog Home | Michael Duquette by Michael Duquette and used with permission of the author. All other rights reserved by the author.

Time for some more REST

This week I have chosen to deepen my understanding of REST API. The article, “RESTful API Design Tips from Experience” by Peter Boyer, goes over good RESTful design practices. The article covers many topics, including some I do not have experience with but are still useful for a greater understanding overall.

The article proposes that the API should state its version
in the URLs. The author suggests adding a prefix to all URLs to specify API
version. This makes the eventuality of version updates easier to handle.

A simple tip mentioned in the article is the use of plurals.
When designing endpoints, plurals should be used instead of the singular form.
This is to avoid possible misunderstandings of what the endpoint is used for.

Example:             /orders/customers          VS           /order/customer

Another tip in the article is to use nesting for
relationship filtering. From what I understand, it is better to have multiple
path variables for filtering than the use of query strings. The example in the
article is very clear on the tip. Following this advice will make your
endpoints easier to read.

The author advises to keep your API as flat as possible. He
suggests that creating and fetching data should have a longer resource path
than updating and deleting data. I do not really understand why this is the
case. My best guess is the shorter path reduces unnecessary processes.

The next tip I found interesting was the important, if not
obvious, idea for pagination of results. When working with larger databases, requests
can have thousands of results. Since it would be impossible to display all the
data, it makes sense to partition the results into pages and return one page at
a time. Pagination can also significantly reduce the expense of a request.

The last tip I will mention from the article is the usage of
status codes.  HTTP status codes should
be used consistently and properly. This means the status should use the proper
code and provide additional details when necessary: an error code with a
message of why the error occurred.

Overall, I found Boyer’s article to be very informative. I
only mentioned a few of the topics raised in his article but all the topics are
interesting and useful. Reading through this article gave me a better
understanding of the nuances of RESTful API design and has helped me comprehend
my current coursework (CS343) better. I suggest to anybody that is new to REST
to read this article.

Article Referenced:
https://medium.com/studioarmix/learn-restful-api-design-ideals-c5ec915a430f

From the blog CS@Worcester – D’s Comp Sci Blog by dlivengood and used with permission of the author. All other rights reserved by the author.

Adventures in TypeScript

This week in CS-343, I was introduced to TypeScript, a
scripting language that uses typed variables to prevent coding errors caused by
mismatching data types. My introduction to TypeScript was my first time working
with a scripting language, and I am really looking forward to learning more
about it and using it to write new kinds of programs. However, the tutorial I
did in class was rather simple, as it only showed how to set up a basic project
in TypeScript. To learn more about this new language, I decided to research
TypeScript’s other features. I eventually came across a useful blog post by
Nwose Lotanna titled “New Features in TypeScript You Didn’t Know Exist.”

Link to the blog:

https://blog.bitsrc.io/new-features-in-typescript-you-didnt-know-exist-54b7ab8d0b4f

As the title suggests, this blog post discusses several
features of TypeScript that were introduced between versions 3.0 and 3.4. Each
feature has a short description that explains why it is useful, and many are
also demonstrated using example code. The post seems to be targeted at developers
who are experienced with TypeScript, which made it difficult for me to
understand every feature it discusses. However, there are a few features listed
in the blog that I could definitely see myself and other newcomers to TypeScript
making use of even in simple programs. I chose to discuss this blog to help spread
information on these useful but often overlooked features.

The first feature discussed in this blog is project
references. As of TypeScript 3.0, it is possible for one TypeScript project to
reference another by referencing its tsconfig.json files. This feature is
heavily reminiscent of the import feature in Java or the #include
feature in C, which have proved invaluable in my experience. Having the ability
to reference code in other files helps keep projects simple and organized, which
will undoubtedly be just as important in TypeScript as it is in other
languages.

Another feature discussed in the blog that caught my
attention is TypeScript’s BigInt object. BigInt was introduced in
TypeScript 3.2 and allows programs to use numbers greater than 253.
While I can’t recall a time where numbers that large were necessary, it is nice
to know that the option exists in TypeScript. There are certainly potential
uses for such large numbers, such as the Fibonacci function that Lotanna uses
to demonstrate the feature. Should I ever need to write a program that uses
numbers of this magnitude, I would certainly take advantage of TypeScript’s BigInt
feature.

A third TypeScript feature that I expect to be useful is the
const assertion. Since TypeScript 3.4, it has been possible to declare
arrays and objects as read-only constants using the syntax demonstrated by the
example code in the blog post. Though the syntax is different, this feature
seems to function just like C’s const and Java’s final keywords.
Having used these features frequently, I expect TypeScript’s const
feature to be useful in many programs to ensure that the values of certain variables
cannot be changed.

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

TypeScript/JavaScript

Ever wanted to build a website and be able to add in
interactive elements to the page? With JavaScript this can all be accomplished.
JavaScript is a programming language that is used with websites in order to
make the design better, sleeker and an overall better website. JavaScript can
also allow for people to create games and apps as well. These games would be browser
based and would allow for the creator to be able to implement the useful tools
that JavaScript provides. Mobile apps are starting to come around to JavaScript
as well. However, JavaScript is not always the easiest to learn or pickup. That’s
where typescript comes in handy.

With typescript, users are able to code with a far more interactive
interface. Once the typescript is written, there is a TSC or type-script
compiler that compiles the typescript code and converts it into JavaScript.
This allows for a much easier integration of JavaScript because of the ease of typescript.
Typescript is a rather new concept, only recently appearing in 2012 by the
creator Anders Hejlsberg. Typescript has many advantages to it over JavaScript.
For starters TypeScript, as mentioned before, is far easier to code and the
user does not have to worry about it being converted into usable JavaScript. TypeScript
is also open-source, meaning that the software for its development can be used
by anyone which allows for constant improvements to be made to the software.
TypeScript also comes with development tools built in. With these tools,
debugging becomes far easier to do and allows for different types of testing.
Another great feature that TypeScript has is that it can function with REST
parameters. REST is a type of software design that I have mentioned previously
in this blog. Another benefit of the TypeScript language is that it is an OOP
language, or object-orientated programming language. This allows for TypeScript
to be easy to maintain and keep clean.

TypeScript is essentially the next phase of JavaScript
because of the fact that TypeScript is a superset of JavaScript. This means that
every feature that JavaScript normally has is implemented with TypeScript. The only
difference is that TypeScript, as mentioned before, has far more additional
benefits to it. When it comes down to choosing whether or not to use JavaScript
or TypeScript, it’s a personal choice. However, since TypeScript was recently
released, it has not had as much time to spread but I believe the obvious choice
would be to switch over to TypeScript because you are missing out on many great
features.

https://en.wikipedia.org/wiki/TypeScript

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

Path Testing

Testing comes in many forms and all are important in their own regard. Path testing is a type of testing used to determine that each path a program can take will produce the correct output. By doing this you are able to determine if there is a fault in the code and where this fault is produced. With path testing you are able to create decision to decision paths or DD paths and you can use these to create a program graph. A DD path is a node in a program that satisfies a certain condition, such as it has one in-degree and one out-degree, meaning there is only one flow of code that can happen that enters the node then leaves. When creating all these nodes they can be assembled into a program graph. These graphs help show the flow of the program and can help with determine how to test your code with path 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.

Clarifying Edge Testing


I happened upon a very
interesting blog recently, searching for more examples of edge case testing,
wherein the author provides an interesting set of common edge cases. While they
use the same names or similar ones as those we’ve seen lately in class some
have new meaning here. In addition, they may have an actual value tied to the
name – such as zero, one, and two – but their values are defined otherwise.

 In order they
are as such:

  • Zero “represents
    any form of null input”, including the actual value zero but also null, an empty
    List or Array, et cetera. This of course is to test the capability of a program
    to deal with input that isn’t properly usable by it.
  • One represents what
    we have referred to as nominal up to this point, meaning a valid normal input
    which should test proper functionality of a program under ideal conditions.
  • Two does not
    correspond to the value two, but rather refers to testing the same code twice,
    usually in sequence, to see how repeated executions affect a system.
  • Two to Max-1 is
    most like one, in that it represents a nominal value as well, but in opposition
    this value should not be the absolute simplest needed to function but an average
    use case; meaning possibly complicated.
  • Max is
    fairly self-explanatory, used to test the upper limit accepted by a program, and
    can sometimes be an extreme value. As such, it can test the limits of the
    program under incredible load.
  • Max + 1 is
    used to ensure that limits placed on an application are working and that anything
    that does not correspond to a valid range is rejected in a reasonable manner.

These would most closely correspond to Normal Boundary Value Testing as we have covered in class but they are each less abstract than those counterparts. They provide an insight on what these values look like in actual QA testing, as well as expectations upon being used. Two for example does not have an actual value associated with it, but rather refers to a testing orthodoxy outlined above. One example of a test in this vein is found in another blog, in which the author proposes the edge case of the same user trying to log in from two different computers. I believe between the two of these blogs a clearer picture of the concepts we have covered can be found through these more concrete examples of the testing procedure.

Sources

A Beginner’s Guide to Testing: Error Handling Edge Cases
Build Strong Edge Test Cases

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.

SOLID – Like a (Open/Closed) Rock

TLDR: your code should be open for extension but closed for modification. o Keep the current functions, Classes, modules immutable o Extend, in a composable way (try to avoid inheritance as it tends to couple things) Read the full article about the Open/Closed Principle from CodeBurst here The main idea is that in one part of your code you have your abstractions such as classes that do one thing and do it well. You don’t want to be modifying them and should be keeping them clean and cohesive. You ready for this? The Open/Closed Principle = COMPOSITE DESIGN PATTERN – mind blown! How about that, we’ve come full circle back to design patterns. Now… where’s that duck? Don’t get your beaks out of joint, no ducks this time we are going to be working with coffee machines instead. I really enjoy a great cup of coffee! This article over on Stackify has a great code example of applying the Open/Closed Principle to a CoffeeMachine app. To summarize: You have a BasicCoffeeMachine Class it has a constructor, a public method to add ground coffee, and a public method that brews a filter coffee. A BasicCoffeeApp class that prepares a HashMap with ground coffee, instantiates a BasicCoffeeMachine object, and calls the prepareCoffee method to brew the coffee. Pretty simple right? Our app brews us a fresh pot of filter coffee. Well what if we upgrade our pot to include an integrated grinder? Now we can brew espresso also but our CoffeeApp doesn’t support this kind of brewer. Sounds like some code changes to the CoffeApp are in order. Why don’t we also update it so that we don’t need to adapt to future types of coffee machines. So how do we do this? Well, let’s start off by extracting what we can to create an interface. Let’s pull out what’s mandatory for controlling a coffee machine, but none of the optional stuff. Since the only real “control” in the BasicCoffeeMachine is the brewCoffee method we can put that up in an interface and have BasicCoffeeMachine implement the interface (CoffeeMachine). Now we can add more implementations of CoffeeMachine. See what we’ve done there? Just by adding the interface and implementing more variations of the CoffeeMachine we’ve adopted the Open/Closed Principle. So, what’s next? We’re not done refactoring, we need to modify the CoffeeApp to make use of the CoffeMachine interface by instantiating instances of it for the different coffee types. Make mine a tall black with a shot of vanilla and please go check out the code example and the full article here. #CS@Worcester #CS343

From the blog Home | Michael Duquette by Michael Duquette and used with permission of the author. All other rights reserved by the author.

SOLID – Like a (Open/Closed) Rock

TLDR: your code should be open for extension but closed for modification. o Keep the current functions, Classes, modules immutable o Extend, in a composable way (try to avoid inheritance as it tends to couple things) Read the full article about the Open/Closed Principle from CodeBurst here The main idea is that in one part of your code you have your abstractions such as classes that do one thing and do it well. You don’t want to be modifying them and should be keeping them clean and cohesive. You ready for this? The Open/Closed Principle = COMPOSITE DESIGN PATTERN – mind blown! How about that, we’ve come full circle back to design patterns. Now… where’s that duck? Don’t get your beaks out of joint, no ducks this time we are going to be working with coffee machines instead. I really enjoy a great cup of coffee! This article over on Stackify has a great code example of applying the Open/Closed Principle to a CoffeeMachine app. To summarize: You have a BasicCoffeeMachine Class it has a constructor, a public method to add ground coffee, and a public method that brews a filter coffee. A BasicCoffeeApp class that prepares a HashMap with ground coffee, instantiates a BasicCoffeeMachine object, and calls the prepareCoffee method to brew the coffee. Pretty simple right? Our app brews us a fresh pot of filter coffee. Well what if we upgrade our pot to include an integrated grinder? Now we can brew espresso also but our CoffeeApp doesn’t support this kind of brewer. Sounds like some code changes to the CoffeApp are in order. Why don’t we also update it so that we don’t need to adapt to future types of coffee machines. So how do we do this? Well, let’s start off by extracting what we can to create an interface. Let’s pull out what’s mandatory for controlling a coffee machine, but none of the optional stuff. Since the only real “control” in the BasicCoffeeMachine is the brewCoffee method we can put that up in an interface and have BasicCoffeeMachine implement the interface (CoffeeMachine). Now we can add more implementations of CoffeeMachine. See what we’ve done there? Just by adding the interface and implementing more variations of the CoffeeMachine we’ve adopted the Open/Closed Principle. So, what’s next? We’re not done refactoring, we need to modify the CoffeeApp to make use of the CoffeMachine interface by instantiating instances of it for the different coffee types. Make mine a tall black with a shot of vanilla and please go check out the code example and the full article here. #CS@Worcester #CS343

From the blog Michael Duquette by Michael Duquette and used with permission of the author. All other rights reserved by the author.