Category Archives: Week-15

Software Architecture as a Career

For this week’s post for software architecture, I decided to explore pursuing it as a career. I have focused several of my posts in this blog to going into a career for software architecture and quality assurance, but software development is very appealing to me as well.

Although I have found this class more difficult than the quality assurance class, I find the work we have done in this class very satisfying, and I would like to do something like this in my career.

I found an article from “Lifehacker,” where they interviewed a software architect Harrison Ambs on what it was like to be a software architect. It focused less on what a software architect is, and more gave general career advice for someone in the industry.

The final question in the interview said, “What advice would you give to those aspiring to join your profession?” He gave a paragraph with some good advice. (Starting with, “Always be willing to learn something even if you know you’ll be terrible at.”) However, I wish more of the article expanded on this and made this more of the focus of the interview.

In one of the answers, he said he worked around 45 hours a week. There were a lot of answers that were like this, and these sort of things are good to know for seeing what a career in the field would be. However, they were good to know, but these didn’t seem like the most important things that the article could be focusing on

I suppose they didn’t want to flood the article with jargon that someone who was outside the discipline or was just starting wouldn’t know, but I think they missed a great opportunity to inspire someone to become a great architect.

There was some good information in there, though. He said he is always learning from blogs and newsletters of “as many individual app developers as possible because these people are honed like a samurai blade when it comes to software development.”

That is good to follow through on as I am pursuing my craft. It is always good to be continuously learning and growing your skills and mindset. This is something that these blogs have made me start doing, and it is something that I would like to continue to develop.

https://lifehacker.com/career-spotlight-what-i-do-as-a-software-architect-1699203274

From the blog Sam Bryan by and used with permission of the author. All other rights reserved by the author.

Fakes, Mocks, and Stubs

https://blog.pragmatists.com/test-doubles-fakes-mocks-and-stubs-1a7491dfa3da

A test double is a generic term used for objects that look and behave like their production equivalents, but are actually simplified. Test doubles are used to reduce complexity and verify code independently from the rest of the system. There are many different types of test doubles, and misunderstanding or mixing them will make fragile tests. This blog post discusses three different variations of testing doubles: fakes, stubs, and mocks.

Fakes are objects that have working implementations different from production ones. An example is using an in-memory data repository instead of accessing a database. The benefit of this is that integration tests can be carried out without performing the time-consuming process of starting up and requesting information from a database.

A stub is an object that holds predefined data and answers calls during tests with this data. Stubs are used when we don’t want to involve objects that would answer with real data. For example, if there is an object that needs to get data from a database to respond to a method call, a stub can be defined with the data that should be returned instead of using the real object. Stubs are preferred for methods that return some result and do not change the state of the system because it allows verification of a method’s return value.

Mocks are used for methods that change the system state but don’t return any value. Mock objects register the calls that they receive. Assertions are used in testing to verify that all expected actions were performed. Mocks are commonly used when we don’t want to invoke production code or when there is no easy way to verify that the intended code was executed.

This blog was a good overview of the differences between fakes, mocks, and stubs. Reading this helped to solidify what I learned in class and gave me a better understanding of when each test double would be used. I especially liked the images and code examples used as they made the idea behind each one easy to understand. Overall this was a well-written and useful blog post that gave me a deeper understanding of material learned in 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.

Testing with Dummys

Today I will be talking about testing software! More particularly, testing by using dummys! So what exactly is a dummy and why do we use it in testing. Dummys are objects that are created for the purpose of testing but are actually never used. Think about it like a mannequin. The mannequin displays the clothes as how they would look on a human, but the mannequin is not actually a functional human, and does not actually use the clothes. Its only job is to make sure the clothes look (or function for the sake of testing) correctly. According to this blog by Tom Winter, “How our test data generator makes fake data look real”,  our test generator makes fake data look real for the purpose of testing our code. Why would we ever want to test fake data? The easy answer is this: sometimes we do not have all the data or all the code finished, and we want to test our code without having to play the waiting game. Sometimes it is even impossible to test our own code without dummys because we do not have access to the actually data. So we use these dummy objects to play the role of the real data (which we do not actually have access to, remember?) in order to test our code to ensure it functions properly.

Testing with dummy objects is something we have been doing in my software program at school, and I happen to find it very useful in the sense that I do not actually need the data to make sure my code works. Not only does this help pick up testing efficiency,  but it cuts down on the overall wait-time between developers and getting their product out. On the flipside of things, if another developer was waiting for me to finish my code before testing, they could use a dummy to test their code instead of rushing me to finish, which could possibly lead to me making mistakes and end up slowing down the entire development process. I enjoy being able to test right away, and using dummys can help with this. I hope to continue using dummy testing in the future, as it is an easy and very effective method of testing!

Here’s the link: https://medium.freecodecamp.org/how-our-test-data-generator-makes-fake-data-look-real-ace01c5bde4a

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.

Journey into Mutation Testing

As I take another step towards Software Quality Assurance Testing. The blog I will talk about is “Mutation Testing: Watching the Watchmen” by Jasper Sprengers.

This blog is about an automated (unit) tests more commonly known as a mutation testing framework. This is a testing tool that purposely insert small changes that would cause a change to the the original code in order to verify your code against the intentional bugs that are created through this mutation testing framework. This testing framework is used in order to test and improve your code in a fun way. The writer also tries to stress the importance of unit testing and how integration testing is just as important if not more. Testing is important because it helps provide quality to your code. In order to be able to test your code you must understand it and what it is meant to do. It also covers “How to make sure our test are any good?”, that would be good code coverage and making sure test suite are testing a wide range of code that assure that most of your code is tested and that test are checked.  Using mutation testing is a pretty good way to make sure you have successfully written good test. Since mutation testing purposely changes your program test to cause it to fail. When test successfully fail then that means that a ‘mutant’ was successfully killed. If test pass then that means that a ‘mutant’ survive which means a mutant was not successfully killed making your test a not so good one after all. According to the writer a “useful mutation testing framework for Java is pitest.org“. In summation of what is talked in the blog using mutation testing framework would make you test your code more seriously without using shortcut.

I found this blog to be very interesting and useful. I like that it stresses the importance of having good test suites to insure quality and how it mention that using mutation testing framework will help insure that you have good test suites. I found the link to a mutation testing framework very useful.  I do not disagree with much of this blog. In fact I find it interesting enough to recommend others to read it. The title of the blog above provides a link to the blog, I suggest you check it out. Thank you for your time. This has been YessyMer in the World Of Computer Science, until next time.

 

From the blog cs@Worcester – YessyMer In the world of Computer Science by yesmercedes and used with permission of the author. All other rights reserved by the author.

Security Breaches and User Information

User data that is stored on websites is very important to keep secured. Although there are some technicalities when signing up for websites that allow you to upload pictures, movies, or other media, you should always take certain precautions when uploading anything to online. Security breaches are no surprise and with massive social media websites such as Facebook, Twitter, or Tumblr, there are bound to be hackers trying to break in the back end to rob and dump data. Unfortunately, breaches like this aren’t too uncommon. Just recently, Facebook was hit with an enormous security breach. About 6.8 million users’ data have been exposed. With a company as large as Facebook, you would think that their security and software back-ends would be able to block attacks, however this is obviously not the case. So what exactly happened? A bug slipped through in the API, an overlook by the software QA team at Facebook.

Facebook released a statement saying that their Photo API had a very vulnerable bug that let app developers access the photos of over 6 million users. The worst part of it was, the bug wasn’t noticed until 12 days after it had occurred. Not only were the users of Facebook affected, but app developers that utilized Facebook’s Photo API also suffered the consequences of this too. Reportedly, there were over 1500 applications that utilized this API.

What can we learn from this? Software testing is not exclusive to how code or programs run, but it also applies to security. There are teams that are dedicated to only testing for security and backdoors in programming for this reason – so the end user can be confident in their products. One small error in the quality of Facebook’s Photo API caused a major breach with a ton of collateral damage. Over 700 app developers and over 6 million Facebook users were affected by this. Interestingly enough, this isn’t Facebook’s only massive data breach in recent times and their end users are definitely not happy about it. Repeated vulnerabilities like are not good and are detrimental to a software’s future in quality and security. Making sure that you have protocols in place that check for these is very important to avoid these types of situations.

 

Article: https://fossbytes.com/facebook-hit-by-another-security-breach-6-8-million-users-photos-leaked/

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.

Procedural and Object Oriented Programming

I am writing in response to the blog post at https://www.codementor.io/learn-programming/comparing-programming-paradigms-procedural-programming-vs-object-oriented-programming titled “Comparing Programming Paradigms: Procedural Programming vs Object-Oriented Programming”.

Object oriented programming seems to be the focus of all that is ever taught in a computer science course after the basics of syntax and control structures are covered, which are the basis for procedural programming. The shift into object oriented programming seems to mostly be for the sake of establishing proper design principles such as encapsulation and normalization to reduce redundancy, but these are not mutually exclusive features of the object oriented programming paradigm; it is still entirely feasible to write procedural code that is still “good” code.

The blog post does not directly define what procedural programming is about, but it alludes to the writing of straightforward code that makes use of variables, scope, functions and control loops. Then comes the brief anecdote of writing thousand-line long programs that start to become difficult to maintain, and how the object oriented programming paradigm is the solution. Object oriented design is definitely helpful for improving the scalability of a large program by introducing better organizational practices to the code structure, but the principles of encapsulation and modularity can be applied directly to the poorly maintained program anyway without changing paradigms. This is not to say that object oriented programming is bad or unnecessary, but the point is that procedural programming is not bad and does not need object oriented programming to “fix” it. Procedural code happens to be the most common poorly written code because it is most commonly used by beginners, who learn about better coding practices once introduced to object oriented programming.

Some of the faults with object oriented programming are described in the blog post, adding that it is not the best idea to avoid the use of procedural programming for the sake of adopting the exclusive use of object oriented programming. Modularity regarding class extensions and modification of a class can make things difficult in languages that focus on object oriented programming, where overriding a method or re-implementing a class may have adverse effects on subclasses. It is ultimately decided that multi-paradigm programming is a good choice, where the benefits of procedural and object oriented programming can be combined.

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

The Iterator Design Pattern

Today I learned more about the Iterator Design Pattern and how it specifically applies to Java. The reason for choosing this topic is that during my project and talking with others the Iterator has come up a number of times throughout this semester. Now, I already knew about the Iterator in Java from taking Data Structures, but I never realized it was a design pattern before this course. The Iterator is actually a Gang of Four design pattern and it is classified as a behavioral pattern with object as the scope (GoF 257). The article gives a short summary of the iterator pattern and the reason it is used in Java. It is basically a way of accessing elements in a collection in order without having to know about the internal representation of the structure, a nice way of using abstraction. The author then gives a nice simple example in Java of how to use the Iterator pattern to access a collection of elements. He does this by creating a basic shape POJO with an id int and String name and stores them in another class that is an array of shapes. He then creates an Iterator class that defines the next element and if there is another element after the current one. This may be my favorite design pattern I’ve seen yet. It is simple to implement, but yet effective at its purpose, especially the way this article showed its implementation. I really like that once you’ve created an iterator for a type, all you need to do is pass in a collection of elements to it in order to process it. When I was working on the backend for my project I realized the need for something like an Iterator, especially with all the endpoints that were looping through the whole database. I wish I had implemented this so that I did not have to keep rewriting conditions to check that the data wasn’t out of bounds. In the future when I create my own programs with collections of elements I will make sure to implement an Iterator so that I can easily cycle through the data without having to worry about how to do it or constantly bounds checking the collection.

Source: https://www.javacodegeeks.com/2015/09/iterator-design-pattern.html

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.

What’s the Buzz about Fuzz Testing?

Whenever I’m testing any of my programs that allow users to input data, I usually try to remember to enter invalid values to ensure that the program does not function when such values are put into the system. Then, in one of my lectures, we briefly covered fuzz testing, which does this process for you! So, I wanted to know more about it and why it is very important to include as part of testing. I found this information from the following tutorial: https://www.guru99.com/fuzz-testing.html.

Fuzz testing, or fuzzing, is used in the context of security testing, where loopholes or vulnerabilities are exposed. It can be a form of black-box testing, so that even without source code, the tester can still determine faults that come up.

The steps that fuzz testing takes to perform are as follows:

  1. Identify inputs taken by the system to be tested
  2. Generate random input or data
  3. Executing tests using this data
  4. Monitoring behavior of the system and its accompanying tests

There are multiple ways that fuzzed data can be created for use, including the 3 listed:

  • Mutation-based fuzzing – alters already-provided, valid data samples to create new test data
  • Generation-based fuzzing – creates new input data based on the type of input needed for the system
  • Protocol-based fuzzing – based on the protocol format specified by the program, invalid data or packets are sent to the program being tested

Through fuzz testing, several different kinds of bugs can be uncovered, which go beyond simply finding invalid input. Some bugs may severely affect the security of an application, like causing memory leaks. Other bugs, called correctness bugs, may come up, which are errors in the overall function of the program. Because it can become time-consuming to come up with many fuzzing inputs, there are various tools that automate and speed up this process.

Fuzz testing provides crucial advantages. It can expose serious security threats and holes in the program which may not have already been covered. If there are other, possibly less significant bugs in the program that may have been overlooked, fuzz testing is a great way to find these as well. However, while fuzz testing is incredibly useful, it cannot be used alone. Rather, it can be a supplement for other testing strategies that may be used to enhance security testing or discover other bugs. Fuzz testing only really looks for simple errors that may arise from invalid input, but there can easily be other, more complex bugs in the program as well.

This post concludes my blogging for the fall semester! Thanks for reading, and I’ll be back next semester!

 

From the blog CS@Worcester – Hi, I'm Kat. by Kat Law and used with permission of the author. All other rights reserved by the author.

Code “Smells” – They Stink!

This post will discuss more bad practices when coding that focus less on design patterns (post about anti-patterns here: https://kathleenmlaw.com/2018/12/03/some-software-development-anti-patterns/) but more so on problems in source code that may cause a bigger problem in the program, called code smells (reference found here: https://sourcemaking.com/refactoring/smells).

The most common code smells can be grouped into several categories. I have included 3 examples of each code smell that can arise, though there are other

  • Bloaters – code (like classes or methods) that grows so large that it is difficult to work with
    • Long methods – methods longer than 10 lines are probably too long
    • Primitive obsession – use of lots of primitives in code rather than creating smaller objects, or many different constants
    • Long parameter list – more than 3 or 4 parameters used when calling a method
  • Object-orientation abusers – code that incorrectly implements object-oriented concepts
    • Switch statements – switch statement has many cases, or conditional has multiple “if” branches in a row
    • Temporary field – only have a value when needed by objects in the program, and are otherwise empty
    • Alternative classes with different interfaces – two classes with the same function but only differ in method names
  • Change preventers – code that, when changed in one spot, requires change in other parts of the code as well
    • Divergent change – changing many methods that are unrelated when making change to a class
    • Shotgun surgery – when making any changes to code, the developer has to make many other modifications to different classes
    • Parallel inheritance hierarchies – when creating subclasses, the developer has to create subclasses for other classes at the same time
  • Dispensables – unnecessary code that would increase readability when removed from the program
    • Comments – when code is full of comments that it is difficult to even read the program
    • Lazy class – a class that doesn’t really have much function in the overall program
    • Data class – a class that only has fields and accessor/mutator methods and serves as a data collector for other classes to use
  • Coupling – code that contributes to coupling (where one section of code may depend heavily on another section, and changes in the former results in forced changes in the latter)
    • Feature envy – when a method accesses data of another object more than its own
    • Inappropriate intimacy – when one class uses internal fields of another class
    • Message chains – when one method calls another, which calls another….

 

I have absolutely made several of these mistakes in my programs, so I’ll be sure to keep a look-out when coding in the future.

 

From the blog CS@Worcester – Hi, I'm Kat. by Kat Law and used with permission of the author. All other rights reserved by the author.

What are Mutations, and How Do They Help Testing?

When I thought of the word “mutation,” I tend to think of it with negative connotation as something that changes internal structure and can potentially cause problems with the structure later on. However, in software testing, mutations have a positive function. This post will go over how mutation testing works, and some advantages and disadvantages of using it. My reference can be found here: https://www.guru99.com/mutation-testing.html. When going over mutation testing during lecture, I found the subject very interesting, and this website provided great further information about it.

Mutation testing takes a program and changes around various statements (introducing faults) in the source code, so that when running unit testing or other testing suites on the program, the tests written for the original program should fail, if they had already passed before. So, when the mutant program fails the test case, then the mutation is “killed.” If the mutant program still passes the test case, then the mutant “survives,” and the tests should be written differently so that they not only pass the code that is originally written, but they also fail other possible scenarios, whether or not those other scenarios were explicitly written in the program.

There are many different kinds of mutations that can be created and used, and they fall under 3 categories: operand replacement operators (which replaces operands in an expression with another operand or with a constant value, like changing x > y to x > 5), expression modification operators (which modifies an operator in an expression, like changing x > y to x <= y), and statement modification operators (which modifies the logic of the program by changing or deleting different statements, like removing an “else” branch of an if-else conditional).

This method of testing provides several advantages. It can uncover missing test cases that weren’t already included in the test suite. It also points out the different places in source code which may be vulnerable to error. It looks beyond simply statement and branch coverage to find any faults which may be overlooked. This enhances the quality of software testing taking place on the program.

However, there are still some disadvantages of using this testing strategy. Because there are many places in source code where these mutations may take place, it would be tedious to manually insert the faults, and automation is a necessity. Time may also become an issue, because each mutation requires a run through the test suite. Finally, this method would not be appropriate for black-box testing, as it involves directly examining the source code.

From the blog CS@Worcester – Hi, I&#039;m Kat. by Kat Law and used with permission of the author. All other rights reserved by the author.