Category Archives: WSU

A Summary on Unit Testing

Unit testing is a crucial aspect of software development that focuses on testing individual components of a software product. Nickolay Bakharev writes a great article detailing the uses, advantages, and strategies to unit testing in his article, Unit Testing: Definition, Examples, and Critical Best Practices.

Unit testing involves writing tests for functions, procedures, methods, objects, or other entities in an application’s source code. The goal is to ensure that each unit of the software performs as intended and meets requirements.

Some advantages of unit testing are that it is able to detect problems early, thereby reducing costs. It is also heavily test-driven, easier to refactor the code, and allows developers to keep documentation of the system’s behavior.

Unit tests usually consist of four phases:

1. Planning and setting up the environment

2. Writing test cases and scripts

3. Executing the tests

4. Analyzing the results

A common approach to unit testing is something called Test-driven development (TDD), where tests are written before the actual code, resulting in a high-quality, consistent codebase.

Unit testing can also be used for security purposes by creating tests that focus on the security controls of the smallest testable unit of software. Security unit tests can help catch security flaws early in the development lifecycle which saves the costs of potential security breaches.

Various unit testing techniques include structural unit testing, which examines the internal structure of the code, functional unit testing, which tests the functionality of an application component, and error-based techniques such as fault seeding and mutation testing.

There are many examples of unit testing in specific frameworks. Some include Android unit testing, Angular unit testing, Node.js unit testing using Mocha, and React Native unit testing using Jest.

In order to use unit testing most effectively, the developer must write readable tests, write deterministic tests that always pass or fail on the same code, automate unit tests in a continuous integration process, and avoid multiple asserts in a single unit test to maintain clarity and reliability.

I found unit testing to be a very useful technique to learn in class. While I knew the basics of testing, this was the first time I actually implemented it into code. I will try to add these unit testing techniques to my research project code.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Sprint 1 Retrospective Blog

Being the first sprint of the Capstone class, there was a lot for me to learn working as a team and also as an individual.

As a team, we all worked very well together in all stages of the sprint. There was good communication which helped us coordinate meeting times both online and in-person. Evidence of our synergy would be through the fact that we were able to meet our estimated 20 weight completion by the end of the sprint. I would attribute the large success of our sprint to our commitment to meeting at least once in person every week throughout the duration of Sprint 1. This allowed us to really work together as team to figure out the issues and workflow, which was brand new to us all.

However, it was not all sunshine and daisies. The team made multiple mistake along the way which had slowed us down on occasion. Two big problems for all of us was navigating GitLab and getting used to the workflow. Aside from getting lost and figuring out the UI, we were unsure at first how to post our issues and how to create branches for our changes. It was also confusing how and when to approve merge requests. We had waited for all our issues to be completed before doing the review, which created merging conflicts and caused certain pipelines that were dependent on the other issues to fail.

For the next sprint, we plan to have a “Workflow tips” shared document that includes all our mistakes from Sprint 1 and their solutions so that we do not make the same mistake again. For example, instead of waiting to review everything at the end, the team will review issues as they are completed. We also know to create merge requests directly from the issue, and to edit the merge request properly so that it meets all workflow requirements.

As for me, an individual member of the team, I acted as SCRUM master and worked to communicate with the professor for the team during meetings, preparing notes and organizing the thoughts of the team. However, I had failed in some parts to organize tasks for myself, missing one stand-up post due to negligence. Now that I have a better understanding of how the workflow and meeting dates work, I will be more prepared in the next sprint.

Activity links:

GitPod Dev Environments: https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/guestinfosystem/guestinfointegration/-/issues/23
Description: Moved Settings and Extensions from VSCode to GitPod Dev Environments.

Add AlexJS Linter: https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/documentation/-/issues/6
Description: Added AlexJS Linter to pipeline check.

Move `commands` to `bin`: https://gitlab.com/LibreFoodPantry/client-solutions/theas-pantry/inventorysystem/documentation/-/issues/5
Description: Changed command folders to bin to avoid naming convention conflicts.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Apprenticeship Patterns: Expose Your Ignorance

One of the patterns addressed in Chapter 2 of Apprenticeship Patterns by Dave Hoover and Adewale Oshineye is titled “Expose your Ignorance”. It is a pattern that helps a programmer identify their weaknesses so that they can better know how to promote their personal growth.

When a company hires a software developer, they are trusting that the software developer is well suited for the job and knows what they need to know to do the job well. However, sometimes even the most experienced developer may come across an issue or technology with which they are unfamiliar.

To combat this, it is necessary to “expose your ignorance”. This does not necessarily mean to down-sell oneself by listing out all weaknesses and struggles, but rather, to be open with one’s learning progress and improvements. Being open is a road that leads to trust and reputation in any software developing team.

How does one healthily expose ignorance?

Ask questions! Learning from experienced software developers is the most direct way to becoming an experienced software developer oneself. Asking questions exposes ignorance, but it also exposes one’s ability and willingness to learn.

What happens if one does not expose ignorance?

The opposite to exposing ignorance is hiding it, and while it may save face in the short term, hiding ignorance will only stunt personal growth. This is bad for both the software developer and the team who depends on the software developer to be able to do their job well.

What are my personal experience with exposing ignorance?

When I was starting off with my research projects, I suffered from “imposter syndrome”. There was simply so much I didn’t know and had to learn to catch up and progress through my research. However, instead of hiding in my shell and trying to keep up a facade, I swallowed my pride and let my advisor know when I wasn’t understand something, or when I needed help. I had to remind myself that this fellowship is a chance for me to grow and gain experience! My advisor does not expect me to know anything and is there to help me learn.

Because I was willing to ask questions and exposed my ignorance, I was quickly able to learn and gain a deeper understand of my research project.

From this experience, I became to like being surrounded by people who know more than I do because it gives me the opportunity to learn so much. It exposes my ignorance not only to those around me, but arguably more importantly, to myself.

Seeing where I struggle pointed out clearly to me, it gives me the chance to address that weakness by doing the necessary research and practice to strengthen my understanding in an area that I would be otherwise unaware.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

What is White, Black, and Grey Box Testing?

Software testing is broken into three main types: white, black and grey box testing. All three types have the same goal, however, they achieve these goals differently.

The blog “Black box vs white box vs grey box” from Shake does an excellent job in breaking down and explaining the unique roles of each testing type.

Black box testing:

The black box testing type focuses on the interface of the software. Software testers working with this type of testing approach the application from the user’s perspective. Because of this, no code of the program is required.

Usually, testers use the basic input/output technique to test the program, making sure that it is working as expected. The main goal of black box testing is to find usability issues and design flaws that affect the user experience.

White box testing:

While black box testing focuses on the user’s perspective, white box testing is all about testing how the program executes its function and therefore needs access to all the program’s code.

The main responsibilities of white box testing include identifying security vulnerabilities, evaluating broken paths, and testing outputs, loop errors, and data flow of the program.

This is achieve through the use of three main techniques:

  1. Statement coverage — it ensures that every statement in the code is run and tested at least once. This process also identifies all the “dead code” or unused statements and branches.
  2. Branch coverage — it is similar to statement coverage, but rather than individual statements, branch coverage ensures that all possible branches of the code are executed by detecting all the conditional and unconditional branches, then executing them.
  3. Path coverage — this technique uses multiple test cases to cover every possible execution path through the software.

The purpose of these technique and white block testing as a whole is to reduce the risks of bugs developing later on development.

Grey box testing:

As the name suggests, grey box testing includes a combination of both white and black box testing. Testers approach the program from the user’s perspective, but with access to some of the internal structure of the program.

The goals of grey box testing include, examining the risk level of all variables in the software, identifying re-occurring errors, and optimizing the number and quality of tests by balancing coverage and effort.

Coming into CS443, the terms “white”, “black” and “grey” box testing were all foreign to me. While I had recalled hearing the terms being said, I never fully understood nor retained the concepts.

This article was very insightful in teaching me the concepts of white, black, and grey box testing. I think realistically, most software testing would be done in the grey box. This is because the advantage of grey box testing is taking the advantages of white box and black box testing. For a final thought, I hope to have the chance to do some white box testing to see what that would look like in a developer setting.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Introduction to Apprenticeship Patterns

The book Apprenticeship Patters: Guidance for the Aspiring Software Craftsman by Dave Hoover and Adele Oshineye is a powerful tool for both beginner and seasoned software developers.

Hoover and Oshineye introduce software development as a craft constantly needing to be honed. The term “craft” has been widely defined and generically used throughout multiple sources. However, Hoover and Oshineye define what they mean by “software craftsmanship” using a list of values. While the list is long and descriptive, the main gist is that the craft of software development is all about improvement. There is always room for improvement, achieved through an open mind, the sharing of information and resources, and the courage to experiment and discover through process.

To help developers hone and perfect their craft, Apprenticeship Patterns contains numerous different strategies or “patterns”, helping the reader not only to grow, but to grow most effectively.

One thing that resonated the most with me was the book’s theme on the importance of having an attitude of growth. Without such an attitude, it is easy to become stuck in one’s own bubble of perceived competence and thereby losing focus on learning. I could have all the resources available to me, every book, tutorial, guide, and mentor; but if I am not open and willing to move away from my perceived area of “expertise”, my growth will surely be stunted.

In addition to the right mindset, I found chapter four very insightful, which goes into detail about how a developer also needs a healthy environment where growth is promoted. An environment that fosters learning and communication is the key difference between a struggling software developer and a thriving one. Because of this, a developer should be careful not to be too content being the biggest fish in the pond. There is always another pond with even bigger fish and more nutrients. Hoover and Oshineye emphasize repeatedly how important it is to let go of perceived competence to focus on learning. Sometimes, the best environment is one that is a little uncomfortable.

Software development is a huge field filled with so much potential. There are dozens of languages that take years to fully experience, learn, and understand. All of this — and so much more — is taught through experience and through trial and error.

In addition however, one other important tip from Hoover and Oshineye is to learn from the best of the best. They stress the benefits of reading books which are filled with the knowledge of experts in the field of software development. Reading is the most direct way to gain knowledge made possible through an open mindset and a resourceful, learning environment.

While growth and learning are important, I also think it is important to rest and enjoy the journey. The word “craft” also implies “artistry”. Therefore, I believe a software developer should not focus too much on “becoming an expert” but also to explore and appreciate the beauty of the art of software development.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Apprenticeship Patterns Blog

Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman by Dave Hoover and Adewale Oshineye is a book covering a comprehensive overview of software testing meant to prepare the reader with the knowledge and skills necessary for working as a quality assurance tester.

In the beginning of the book, Hoover and Oshineye answer the important questions of “what” is software testing and “why” it is necessary in software development.

At the highest and most general level, software testing is a way by which a software’s quality is evaluated, estimated, and shared with stakeholders, providing an independent view of the software product. Furthermore, it is the goal of software testers to ensure that this quality meets and maintains the requirements. I found it interesting that the book mentioned the primary function of software testing to be for the stakeholders; however, it makes sense as software testing not only is needed to ensure that the program runs, but also that it runs smoothly for the user, and most definitely for its stakeholders. The best way to assure stakeholders of the product’s success is through software testing.

Chapter two of the book gives further reasoning for software testing stating that the U.S. government lost 60 billion dollars due to software defects in 2002, equating to 0.6% of the country’s gross domestic product. In a world that is so heavily dependent on technology, it becomes evident how important it is to ensure that this backbone of society remains reliably working.

So with the question of “what” and “why” out of the way, the book shifts gears into the essence of software testing. The fundamentals of software testing is split into three parts: testing basics, requirements, and test plans.

The most basic form of testing is checking expected output with the observed output based on a controlled input allowing for a clear comparison and analysis of the program’s behavior. Most patterns of software quality assurance are based on this fundamental strategy.

Before testing software, it is necessary to know what it is that needs to be tested. This is given by the software requirements. These specify exactly what it is a specific piece of software should do under certain conditions ensuring that developers know what to build and that testers know what to test. Requirements are laid out in a test plan, a collection of test cases ensuring that every requirement of a software is met.

Software testing is complex field with many moving parts. However, it all boils down to ensuring that the program works as intended, meeting all the requirements and expectations shared by stakeholders and users, which saves time and money for companies that use it effectively. It is a field of software development that I am very interested in and am excited to learn about more.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Strategies of Behavior Testing

There are many kinds of software testing, behavior testing is one of the more common types. Behavior testing involves a thorough evaluation of a code’s behavior through a controlled testing of inputs. By evaluating the outputs, the developer is able to verify that software is working as intended, to fix the bugs if not, and by doing so ensure that the program meets user requirements.

Because of the numerous scenarios in which a program may be used, it is important specifically in behavior testing to evaluate the code a thoroughly as possible. There are multiple ways to do this. In the blog “What is Behavior Testing in Software Testing?” from codiumAI, five main types of behavior testing strategies are covered. I will share the top three that I found the most useful and interesting.

  1. Functional Testing

    This is a foundational testing type and used in practically every type of testing not just behavior testing. In the context of behavior testing however, the goal of functional testing is to verify that the software performs the specified functions and actions as needed.

    Specifically, functional testing aims to guarantee that the program complies with functional requirements, and when given certain inputs, that it generates the expected outputs. This can be done at the unit or system level to ensure that not only the software as a whole works, but also each individual component of code.

  2. End-to-End Testing

    After all the parts of a program are thoroughly individually tested, the next important step is to test how well all the parts work together to run the entire program. This is the purpose of end-to-end testing. The developers examine the flow of the entire program to make sure that all data and information are passed down through each module correctly and that there is seamless connection between each system.

  3. Usability Testing

    This type of testing is focused more the user experience. Usability testing, as the name suggests, focuses on the software’s user interface and overall user satisfaction. So, instead of checking for code bugs or input/output requirements, developers doing this type of testing are on the lookout for usability issues, poor layout, confusing navigation, or unclear instructions.

    Usability testing ensures that the application not only runs correctly but is also intuitive and pleasant to use at the business/consumer level.

Out of the three strategies of behavior testing, I found usability testing the most interesting because it reminded me that the best applications are the ones that not only do their job, but also do it in an intuitive, user-friendly way. So as someone who is looking to so into software development, it is important to remember to look at the code from a user’s perspective, especially when doing software testing.

Blog: https://www.codium.ai/blog/what-is-behavior-testing-in-software-testing/

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Set-Up Post | Libre Food Pantry & Thea’s Pantry

Libre Food Pantry (LFP) and Thea’s Pantry are both organizations working to provide solutions to those in need by offering alleviation in grocery and other personal needs.

The LFP is developed mainly by instructors and their students who act as LFP Shop Manager and the LFP Shop respectively. Each Shop is further divided into Teams that work to develop and improve solutions.

Shop Managers are not only in charge of their shop and are also members of the Coordinating Committees whose responsibilities are to guide the direction of LFP, represent its high-requirements, support all the Shop Managers, and when appropriate, set necessary policies.

Thea’s Pantry is partners with Libre Food Pantry which is why I found it useful to learn more about how the LFP was organized.

One thing I found interesting about Thea’s Pantry was it’s relation to the Worcester County Food Bank. The pantry sends monthly reports using the Monthly Report system, which is accessed by a Pantry Administrator who specifies the month and year to generate the respective report as a downloadable Excel file.

For this reason, it is important to create a system that is able to reliably log and store activity records of the pantry about both the guests and inventory of the pantry. That is what the collaboration between Thea’s Pantry and the LFP wish to accomplish.

Knowing these facts allows me to see more clearly what I will be contributing to through my Capstone project, as well as the connections that allow it to happen.

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Writing Clean Code in Python

At Worcester State University, I have been learning about programming through the context of Java. However, there are many other programming languages aside from Java. Though they likely follow the same principles and patterns, there are also inevitable differences, or at least a different approach to these same principles or patterns in practice.

The article Best Practices to Write Clean Python Code written by vanigupta20024 goes over Python specific clean code practices. The author presents four main tips:

  1. Clean indentation
  2. Using virtual environments
  3. Modular code
  4. “Pythonic” code

Clean indentation was taught in class under the context of “horizontal openness” or “horizontal spacing”. This principle is necessary for all languages, but it is especially necessary for Python. Python does not use braces to specify code blocks. Instead, it relies solely on space and tab indentations. Because of this, not only is clean indentation required to readable code, it is required for executable code!

Using virtual environments is something specific to Python. It allows the programmer to create a separate and custom environment for their project where any installed libraries and packages are separated from those installed outside the environment. That way, dependencies can be easily shared and managed separately for each project. Instead of having someone install libraries one-by-one, it is much cleaner to have the person run a requirements.txt file to automatically install all the necessary libraries and packages to run the code in one execution.

Modular code is a tool in Python that helps programmers follow the DRY principle (Don’t Repeat Yourself). This makes code clean by allowing programmers to create something like a code library that can be imported and implemented into the Python program without having to have all the code in the repository. Even better, modules can be uploaded into the Python database to be accessed by anyone, meaning that instead of having to create the function themselves, programmers can simply import the function they need to use in their code, making the code less dense and neater.

“Pythonic” code refers to special Python shortcuts that can make code easier to read by simplifying a task that would normally take multiple lines of code. For example, when swapping values, a programmer might initially think to write code this way:

value_a = 5
value_b = 6
temp = 5

value_a = value_b
value_b = temp

However, that is a lot of lines simply for swapping two values with the addition of a third variable. Instead, there is Python shortcut for this that simplifies the process.

value_a = 5
value_b = 6

value_a, value_b = value_b, value_a

Clean code is definitely an aspect of programming that I want to become more adept with. Python is not a language taught at WSU, but it was the sole language I used in my internship and research projects which is why I decided to do research on tips and tricks for clean code through the context of Python programming.

Source: https://www.geeksforgeeks.org/best-practices-to-write-clean-python-code/#

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.

Adhering to the Law of Demeter

Also known as the Principle of Least Knowledge, the Law of Demeter states that objects should avoid accessing data and methods that belong in other classes and instead, only interact with its immediate dependencies (Baeldung).

When used with Object-Programming languages, the goal of the Law of Demeter is to make the components of a program less dependent on each other, loosely coupled, and therefore easier to manage and scale.

There are five rules to the Law of Demeter:

  1. The first states that methods should only call methods that belong to their same class. It is not recommended for a method in class X, for example, to call on another method in class Y.
  2. The second rule expands on the first to say that methods of a class should only call methods that belong to the objects created by that class. For example, a method X of a class Z should only call methods of an object created by method X.
  3. The third rule states that a method should only ever interact with an object when passed to it as an argument. There should be no direct access to the object within the method itself.
  4. The fourth rule allows the method of a class to invoke the method of a class given that it is an instance variable of the same class. For example, method X of class C is allowed to call the method of an object held as an instance variable of C.
  5. The fifth rule is similar to the fourth rule except it states that the method of a class is able to call the method of a static field in that same class, similar to a method of an object of the same class.

When these rules of the Law of Demeter are applied, they help prevent code from becoming tightly coupled, meaning that they cannot operate independently. However, there are some exceptions to certain cases such as for chain calling, fluent APIs, or working with data structures. An experienced programmer will know when and how to effectively apply the law of Demeter.

While refactoring the code for one of my research projects, I had practiced to apply the GRASP principles to the new design. For another project that I am refactoring, now that I am more comfortable with the GRASP principle, I will focus more on applying the law of Demeter to make sure my code is not tightly coupled. This means code that is less fragile, scalable, and easier to manage.

Source: https://www.baeldung.com/java-demeter-law

From the blog Stories by Namson Nguyen on Medium by Namson Nguyen and used with permission of the author. All other rights reserved by the author.