Author Archives: rdentremont58

Parsing HTML and the Document Object Model

In A List Apart’s series “From URL to Interactive“, Blogger Travis Leithead describes in his article “Tags to DOM” how HTML documents are parsed and converted into the Document Object Model (DOM). Through the course of his post, Leithead explains encoding, pre-parsing, tokenization, and tree construction.

The first step to parsing an HTML document is encoding. This stage is where the parser must sort through each part of the input and sent from the server. Since all information computers handle is binary, it is the parsers responsibility to figure out how to interpret the binary stream into readable data.

After all the data has been encoded, the next stage is pre-parsing. During this step, the parser looks to gather specific resources that might be costly to access later. For example, the parser might select an image file from a URL tagged with a “src” attribute.

Next, the parser moves on to tokenization. This process is when all the markup is split up into discrete tokens that can be organized into a discernable hierarchy. The parser reads through the text document and decides which tokens to declare based on the HTML syntax.

Once all the document has been tokenized, each token is organized into what is called the Document Object Model, or DOM. The DOM is a standardized tree structure that defines the structure of the web page, organizing it into sections with a parent-child relationship. The root of the tree is the #document/<html> tag, and its children are <head> and <body>, the body may contain multiple children, and this organization contextualizes the data into a readable layout. The DOM also contains information about the state of its objects, so this allows for a degree of interaction that make complex programs.

I would highly recommend this article and this whole series to any budding developer such as myself, as understanding the entire process of how programs transform from code to an interactive website is integral knowledge. And the authors at A List Apart do a great job being both thorough and concise in their explanations. I definitely feel more knowledgeable after having read this article and found it valuable.

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

The Iterator Design Pattern

Ever since taking Data Structures, where we had to implement different projects and include an iterator object for each of them, I was curious about why exactly they were so pervasive. As it turned out, the Gang of Four had defined the iterator design pattern, and a helpful article on oodesign.com taught me about the motivation/intent of this pattern as well as how to apply it.

The Gang of Four classify the iterator design pattern as a behavioral pattern, as it contains functions that handle accessing the objects in a collection. The motivation behind this pattern is the ability to control and navigate through a variety of different data structures: arrays, lists, trees, stacks, queues, etc. Also, if the type of the objects within these different kinds of collections are the same, an iterator could be used to handle accessing these objects in the same way. Finally, according to the Gang of Four, “a collection should provide away to access its elements without exposing its internal structure”. This is important for security as well as providing a single access point for users.

When implementing an iterator, there should be an interface containing useful functions such as hasNext(), next(), remove(), and other methods that might be necessary. The iterator object itself is implemented as a nested class inside a collection class, so the iterator has access to the local variables and functions of the collection. Structuring it in this way allows different types of iterator objects which handle different collection types to still implement the same interface, and users will be able to process elements in different collections in your program using the same functions.

Reading this article definitely cleared up a lot of misunderstandings I had about the iterator, and definitely made me appreciate its usefulness in the context of cohesively tying together different types of data structures. This article in particular was helpful because it contained examples as well as UML diagrams, and further reading and applications that were slightly beyond my scope at this point. Still, I highly recommend it for anyone who is curious about what the iterator design pattern does.

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

Commonly Used Software Testing Strategies

In this article, The 7 Common Types of Software Testing, founder of the Simple Programmer blog John Sonmez uses his experience to describe common strategies of software testing, explains some of the benefits and liabilities of them, and how they are applied in the world of software development. Sonmez stresses how there are many other methods, and each of these are not used in isolation.

The first Software Testing method Sonmez describes is black box testing, where we are only concerned with the output of the program, and no actual code is given to the tester. The benefits of this method are simplifying test cases to input/output, and tests are from a user perspective. The downsides are the underlying reasons behind errors are not knowable, and cases can be hard to design.

Naturally, the next method the author discusses is white box testing. The pros of having the source code to test are discovering hidden bugs, optimizing code, and faster problem solving. The cons are the tester must have knowledge of programming and have access to the code, and it only works on existing code, so missing functionality may be overlooked.

Sonmez next describes specification based or acceptance testing. This methodology is where preset specifications guide the development process. The main benefit of this strategy is that errors are discovered and fixed early in development. The main drawback is the effectiveness of this method relies on well defined and complete specifications, which is time consuming to say the least.

The next strategy the author describes is automated testing and regression testing. This style of testing is designed to make sure changes in software does not cause problems, and is used where manual tests are slow and costly. Sonmez explains how vital these testing strategies are in Agile frameworks, where software is constantly added to. Automated regression tests are integral to this methodology because the same test cases have to be applied frequently, so automation is more advantageous than manual tests.

While there are more strategies Sonmez describes in this article, and many more in general, I chose to focus on the ones we discussed in class, as the author provides good context and a broad overview of these commonly used testing methodologies that further cement my understanding of these concepts and when to use them.

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

Using the Decorator Pattern

Derek Banas has a youtube channel dedicated to java tutorials and higher level software development concepts. In his video series of design patterns, he describes the value and how to use the Decorator Design Pattern. Banas begins his tutorial by explaining the utilization of the decorator pattern, and then applies it by using a simple example based on a pizza making simulator.

The purpose and value of using the decorator pattern according to Banas is it allows you to dynamically modify an object, without having to hard code additional features. By extension, this allows us to add to old code without having to rewrite the program. Banas suggests to use the decorator pattern in situations where we would want to use inheritance, but where the classes need to be flexible enough to add features to during run time, so inheritance itself is not sufficient. By applying this pattern we are able to favor composition over inheritance.

Banas applies this pattern in an example of a program used to add toppings to a pizza, and display a description and cost. He first implements the solution to this problem using inheritance, hard coding each type of pizza subclass with a preset description and price. However, Banas notes how by using inheritance, we would have to implement an infinite amount of subclasses for each combination of topping. Furthermore, the change in price of a topping would necessitate changing every subclass using that topping. So regular inheritance is not sufficient for this program.

From here out Banas implements the decorator pattern using a Pizza interface, a ToppingDecorator abstract class with a Pizza instance variable, and PlainPizza concrete class. By creating topping classes that extend ToppingDecorator, he is able to add toppings dynamically to a PlainPizza object, calling a string of constructors for each topping (Pizza myPizza = new TomatoSauce(new Mozzarella)…).

I highly recommend Derek Banas’ youtube channel, as he is adept at breaking down high level software design strategies into simple examples anybody can understand, and he is skilled at illuminating the benefits of design patterns over more basic, intuitive implementations. The structure of his videos are easy to follow as well, starting with a high level discussion, moving down to a UML diagram, and finally implementing the solution. This strategy is very helpful for anyone learning or needing clarification on design patterns.

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

Test Driven Development And Unit Testing

Software developer John Sonmez writing for simpleprogrammer.com gives a narrative of his experience as a lead developer, and how he applied the practices of test driven development and unit testing in his article What is TDD? What is Unit Testing?.  Sonmez stresses the definitions in these concepts and illustrates how they are applied in the development process.

Somnez begins by asserting that the purpose of a unit test is to verify the functionality of the smallest possible unit of code, usually on the class level. The author calls unit tests an “absolute specification”, and he explains that the value of a unit test is verifying that the smallest possible units of code function properly in isolation.

According to the author, by making sure unit tests are absolute specifications on the smallest possible units of code, unit testing can highlight problems in the design. Sonmez backs up his claim by describing how unit tests help developers discover tight coupling, and issues with cohesiveness, as the process of testing classes in isolation highlights these issues, since most programs have complex dependencies.

Sonmez moves on to define test driven development as the opposite of the traditional waterfall methodology of testing, where complete specifications were provided up front and tests happened at the end of development of a component. In test driven development, tests are written before any implementation, and only minimal code is written to make that particular test pass. After the tests pass, the developer refactors the code. This process Sonmez describes as “Red, Green, Refactor”, alluding to the red/green color of the unit tests.

The value of test driven development according to Sonmez is that tests are the best form of specifications, they either pass or fail; there is no room for interpreting the specifications. Furthermore, the author asserts that this development style is important because it forces the developer to understand the function of the code before implementing it. If we can’t describe exactly what the test should verify, then we need to go back and understand more, helping prevent errors before they happen.

I enjoyed this article and highly recommend it to anyone confused about how these concepts apply in the industry, as you can tell Sonmez’s professional experience has enlightened him in these areas. He is very good at simply describing concepts and the practical situations and uses of applying them.

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

On the Differences of Test Doubles

In his post “Test Double Rule of Thumb“, Matt Parker describes the five types of test doubles in the context of a “launchMissile” program. Using a Missile object and a LaunchCode object as parameters, if the LaunchCode is valid, it will fire the missile. Since there are dependencies to outside objects, test doubles should be used.

First, we create a dummyMissile. This way we can call the method using our dummy, and test the behavior of the LaunchCodes. The example the Parker gave us is when testing given expired launch codes, the missile is not called. If we passed our dummy missile and invalid LaunchCodes to the function, we would be able to tell if the dummy variable was called or not.

The next type of test double Parker explains is the spy. Using the same scenerio, he creates a MissleSpy class which contains information about whether or not launch() was called, the flag would be set to true, and we could determine if the spy was called.

The mock is similar to the spy. Essentially, a mock object is a spy that has a function to verify itself. In our example, say we wanted to verify a “code red”, where the missile was disabled given an invalid LaunchCode. By adding a “verifyCodeRed” method to our spy object, we can get information from the object itself, rather than creating more complicated tests.

Stubs are test doubles that are given hard-coded values used to identify when a particular function is called. Parker explains that all these example tests have been using stubs, as they all return a boolean, where in practice real launch codes would be provided. But we do not need to know about the LaunchCodes to test our LaunchMissile function, so stubs work well for this application.

The final type of double Parker describes is the fake. A fake is used when there’s a combination of read and write operations to be tested. Say we want to make sure multiple calls to launch() are not satisfied. To do this, he explains how a database should be used, but before designing an entire database he creates a fake one to verify that it will behave as expected.

I found this post helpful in illuminating the differences between the types of doubles, as Parker’s use of simple examples made it easy to follow and get additional practice identifying these testing strategies.

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

On REST API’s

This tutorial What is REST API Design? on mulesoft.com is a beginner friendly description of how REST API’s operate. The first section of the tutorial focuses on defining RESTful API’s and how they are typically used. However, the majority of the post describes the five key criteria that turns a regular API into a RESTful one.

What makes Representational State Transfer (REST) API’s different than other API’s is adherence to predetermined protocols. Like how IP and TCP are a set of guidelines that allow information to be shared over the internet, REST API’s have a set of five criteria that every developer designing this system must follow.

The first criteria is the API must be a client-server architecture. This rule says that the client end and the server end of the system should be separate and have no dependencies. Any changes to the database or the program calling the API should not effect the other part of the system.

Second, the API must be stateless, which means that all calls on the API should contain all the data the server needs to fulfill the request. The client end does not need to store data in the server itself.

Third, when the REST API’s respond to requests, data that is sent to the client should be stored in cache memory, which is faster and reduces stress on the server end.

Fourth, there should be a uniform interface handling communication between the client and server end. Usually, this is done by using HTTP and URL’s. This is a crucial function of the REST API, as there needs to be a common lifeline between the requests and responses.

Finally, the API should be a layered system. This constraint ensures that the program will be divided into layers, each focusing on a particular responsibility and handling communication to the next level above/below. This gives a certain level of security and flexibility between layers of the system.

This tutorial definitely helped my understanding of REST API’s, as the author went into some detail describing each of them and what role each constraint plays in achieving the goal of RESTful API’s.

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

Test Automation and Continuous Testing

Blogger Kyle McMeekin writing for QAsymphony.com in his post “Test Automation vs. Automation Testing” explains the definition and distinction between automated testing and test automation, and also goes into their roles in continuous testing and why this type of testing is important  to understand.

McMeekin begins by defining automation as using technology to complete a task. When applied to the field of software quality assurance, there are two different types of automation: automated testing and test automation. While the terms sound interchangeable, the author differentiates them by explaining how the scope of each is different.

Automated testing is concerned with the automation of executing particular test cases, while test automation is concerned with automating the management of the test cases as an aggregate. While automated testing is actually carrying out the tests we are interested in, testing automation manages the pipeline of all of the automated tests. So the scope of automated testing is more local compared to the more global scope of test automation.

After differentiating between these two types of automation, McMeekin describes how they apply to continuous testing, and explains the importance of this strategy in today’s economic climate. While most software testing is done after development is finished, today more tech companies are using models where the software is constantly in development constantly updated even after it becomes released. In this case, testing must be conducted as soon as something is changed. This technique is known as continuous testing.

However, keeping track of every test suite constantly is a huge task itself. This is where test automation comes in. If we are able to automate the process of managing the processes of this ever-growing list of test suites, a massive amount of work is saved on the tester’s part, freeing up time to create effective test cases.

Automation is at the heart of computer science, as saving work by taking advantage of computer’s abilities to handle processes is integral to being a good developer. So learning how to apply automation in the context of software testing is definitely advantageous. Especially since it is so common nowadays for programs to be constantly added to after release, the amount of tests to keep track of increases steadily. By taking advantage of test automation and keeping track of all the testing processes, we don’t need to worry about the timing of the tests, we can spend more time testing and analyzing the behavior of software.

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

Writing Efficient Code

In the second part of Brandon Gregory’s blog post “Coding with Clarity: Part II“, he starts with the assertion that “Good programmers write code that humans can understand”. In the spirit of clarity, Gregory continues to elaborate on solid design principles that are helpful in software engineering.

The first principle is the Law of Demeter, or as Gregory puts it “the principle of least knowledge”, and describes this principle as an application of loose coupling, another design strategy that states one part of a program should not rely on others. Adhering to this principle will help ensure flexibility if new features are added or modified.

An example Gregory uses that demonstrates this principle is the use of getter/setter methods to provide access to class data as opposed to allowing classes to directly access data. By applying this tactic, it ensures that future modifications do not mess up any other parts of your program, as all modifications will be in the getter/setter methods.

The next programming practice is the Interface Segregation Principle. This is to make sure no object contains methods it doesn’t use. If a class has a bunch of methods, and not all methods are used for each instance, the better strategy is to separate that class into specific interfaces or sub classes. This is a similar goal as the strategy design pattern that we discussed in class.

However, Gregory warns us that abstraction can be taken too far. It is possible to abstract so much that the program contains an excessive number of interfaces or sub classes. The author reminds us that the goal of abstraction is to reduce complexity.

The final principle in the article is the open/closed principle. This assertion is that software should be open for extension but closed for modification. If the program is designed correctly, the implementation should perform as specified and should not be modified. Instead, to change functionality of the program, all that should be done is adding functionality, and not changing any of the existing code.

I very much found this two part series of “coding with clarity” helpful.  Almost all of the principles Gregory explains have been applicable to content we have covered in class. I found his writing style easy to follow and the particular examples he uses to demonstrate the principles are cogent and illuminating.  I recommend them to everybody looking to improve their design knowledge.

 

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

Strategies for API Testing

Blogger Lukas Rosenstock posting for the company website BlazeMeter describes common API test strategies and definitions in his post “API Performance Testing Scenarios and Vocabulary“. While a good portion of the post examines how this particular software can help with this type of software testing, the general strategies and explanations he gives are definitely helpful in identifying meaningful test suites.

Rosenstock first describes Application Program Interface or API testing by defining the two main paradigms: Functional tests and Load tests.

Functional tests, aim to verify that the software functions perform as the specifications prescribes. Testing strategies such we learned in class such as equivalence class testing and boundary value testing can help us determine appropriate values to test in order to verify that the program behaves as expected.

Load tests on the other hand, test other real world complications that are out of the scope of functional testing. The main example Rosenstock goes into is the consistency and response time given an expected amount of user traffic. Load tests are generally functional tests that that are performed on many virtual users to simulate when the program performs in the real world.

From here on, the author describes the various types of load tests; what it is they are testing for and strategies for how to collect the information.

First, stress testing is the process of load testing where you start with a small number of virtual users and steadily increase the sample size and record specific performance times. This strategy gives information about performance at specific intervals.

Rosenstock also describes soak tests. The defining qualities of soak testing is to verify that memory efficiency is achieved. If there are any data leaks or unnecessary variables floating around in the software, and the maximum amount of memory is reached, the program can fail. So soak testing is the process of running load tests over a long period of time to determine that space efficiency is achieved.

I found this post helpful in illuminating even more situations that need to be tested for. While verifying the behavior specifications in a program is essential, there are also other real world situations that must be accounted for, such as the volume of user inputs. In this way, load testing is just as essential as functional testing, and this article definitely helped add to my understanding of the scope of good software testing.

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