Two-factor authentication is a user-verification method used by many web applications and services today. When a user tries to log in, a verification code is sent to a previously specified external device or address, such as a phone number or email. This code usually expires after a set time. The user that requested the code then enters it in the application or program to verify themselves and gain access to their account. By splitting access to your account into multiple different forms, you greatly increase the security of your account. Nobody can log into your email, even if they know the password, if you have two-factor authentication that is being sent through SMS.
David Walsh explains how the system of two-factor authentication is divided up behind the scenes. The first step is to generate a secret unique key for the user to validate two-factor authentication codes in the future. Then, you must add the site to your authentication. Finally, this code must be provided by the user and then validated to confirm it matches what was expected. If not, the user can try again with a new key. Since most two-factor authentication services refresh the key every few seconds/minutes, it is not necessary to lock the user out if they get one wrong.
Two-factor authentication is an incredibly powerful and important new form of security that allows you to put an even tighter lock around your information. As a developer, it is important to consider allowing your users to use two-factor authentication for your application, especially if any sensitive data is stores or if access to your account leads to vulnerabilities in the system. It’s one of those things you don’t realize is so important and valuable until you get your account stolen and realize it could have been prevented.
The article Test Case Design Techniques to Ensure High-quality Software on ReQtest brings up the three major categories test design techniques are generally classified into. These techniques are specification-based, structure-based, and experience-based. Each of these techniques covers different testing methods we covered in CS-443, especially structure- and specification-based techniques.
Specification-based techniques are also referred to as black-box techniques, which should give you some idea of what kind of testing this category covers. Testing techniques under this category are generally written to the technical specifications and client’s requirements. These testing techniques rely more on an understanding of what a program’s intended functions are, and what different states it can find itself in performing those functions. The actual structure of the code is not considered. Using specification-based testing, you can verify that your program works the way it was intended and is written to specification.
Structure-based techniques are conversely referred to as white-box techniques. As expected by the name, these testing techniques test the actual code that is written, and requires knowledge of the code and its internal structure. Many of the testing techniques of this type involving changing conditions and values and making sure code works in multiple cases, validating each branch of the code. Structure-based techniques help highlight any glaring structural or logical issues within your code you may have overlooked.
The final category is experience-based techniques. This category is pretty broad, mostly involving techniques that rely on prior knowledge or information that couldn’t be gained just from testing. This is the type of testing you just can’t plan for. However, the more you test, the more you can apply knowledge from previous tests to fix issues before they become back-breaking.
Dividing the testing into different categories makes their usefulness easier to understand. Structure-based techniques are more difficult and require more knowledge, but are exhaustive and effective at finding issues in the code. Specification-based techniques verify that the parts of your code that matter are functioning correctly. Experience-based testing simply leverages your knowledge of an area to improve testing. All these techniques have valid uses in the world of testing.
In his post Six Things That Go Wrong With Discussions About Testing, James Bach lists six different things that can often go wrong when testers are discussing testings. His six reasons can be summarized as testers misunderstanding the purposes of testing and not following the proper procedure when it comes to testing.
Your goal when testing is to discover any vulnerabilities in your program, but also to find strengths and things your program is doing well. This covers James’ first two points. When it comes to testing, quality is much more important than quantity. It is better to have a more complete coverage of your program and all its branches than to have a bunch of tests doing the same thing and missing different parts of your program. This is why it is important to think of tests as events instead. What is important is what your test is testing and how it goes about that, and it shouldn’t be thought of as some ‘Generic X Test.’
Often times people get carried away with automated testing and rely too much on it. While it is good to use automated testing, developers have strength far beyond that, and should use automated tests as tools to better accomplish effective testing, not as automated workers that do your work for you. Thinking of automated tests in this way also distracts from the purpose of testing, and makes it easier to forget why you should run certain tests in the first place.
James’ last point is probably his most important one. Testing isn’t just some set task that can be navigated a certain way every time. What I’ve learned this year is that testing is about thinking critically about a program and the way it COULD act, and design your tests according to those parameters. Consider where things can go wrong, and try to test the strength of weak parts of your code. But most importantly, be ready to learn, as every program has a different set of tests with a different strategy that is most effective for testing. Testing is a dynamic thing, and testers must be dynamic people.
In his post Back-end Development vs Front-end Development, Mikke Goes explains the differences between back-end and front-end development. He also goes into detail about the places where they intersect. Mikke also speaks briefly on combining both areas of development into what is known as full-stack development.
Back-end development concerns itself with the storage and manipulation of data. For example, when you log into your email, your browsers sends a request to the server to return all the information concerning your account, such as your settings and inbox. The mechanisms behind the storage and transferring of this information is the back-end. Back-end development concerns itself with the parts of a program you don’t usually see, but does a lot of work behind the scenes.
Front-end development finds its responsibilities mostly in the visual aspects of your program or application. All the buttons, text, and input fields on a web page are designed by front-end developers. This gives the users ways to interact with all the information stored in the back-end, creating an interface that bridges the gap between the client and the server. Both the functionality and appearance of web pages can fall under the duties of a front-end developer.
Full-stack development puts it all together. This is an understandably powerful position to operate in, as working on both the front- and back-end together ensures that they will be designed with each-other in mind and written properly and effectively. In CS-343 this semester, we have to work on a project where we are effectively full-stack developers. It is challenging to have to work on both at the same time, but I think working on one helps your understanding of what needs to go on the other end to tie everything together.
Front-end and back-end development are both important concepts. A web application isn’t going to exist without one or the other, and both are ultimately just as important to the end result as each-other. The differences are apparent, which is why it makes sense some people make a living doing one or the other. Ultimately, Mikee makes a good point that understanding both types is a boon to learning how to develop web applications.
The blog post How Do I Know My Tests Add Value? by AutomationPanda discusses the value of proper testing. The author brings up the common issues that sprout from use a bug-fixed count as a metric for successful testing, and highlights why testing is important and can help improve development.
Testing is important because it validates that your program is working as it is expected to. Well-written tests with the proper amount of coverage give you information about your program and whether any changes need to be made. A passing test indicates correctness and that your program is working as expected. A failing test points out a bug that needs to be fixed and helps highlight weak parts of your code.
The absence of testing might not necessarily lead to bugs, but we all know as programmers that even when it seems your code is running exactly as you intended it to, logic errors can happen and sometimes things weren’t written with every situation in mind. When testing is in being implemented, developers are accountable for the code they write, and must think carefully about the issues that may arise.
Tracking bugs isn’t necessarily effective because it encourages testers to find issues even when there may not be any. All tests passing is still good news and a sign of progress, even if it just means you are doing everything right. Enforcing bug quotas and forcing testers to find issues means they will expend effort looking for things that aren’t there and nitpicking small issues rather than writing more tests or making sure they have good coverage, which are far more effective and finding issues in your code.
At the end of his post, the author suggests some different metrics to use: time-to-bug discovery, coverage, and test failure proportions. All of these serve as much more accurate and effective measures of determining whether your testing has value. Whatever metric you use, it is important to think about why you are testing and whether you are doing it in a way that tells you something about your program.
On his blog, Mikke Goes takes the time to explain the Model-View-Controller design pattern in his post What is the Model-View-Controller (MVC) Design Pattern?. He uses the analogy of an ice cream shop to describe the different functions of the components. The waiter is the view, the manager is the controller, and the person preparing the ice cream takes the role of the model. Together, when a customer makes an order, they each can perform their responsibilities and successfully handle the customer’s request.
The Model-View-Controller design pattern separates the components of your code into sections that divide logic from interface. Keeping the functionalities separate from each other will make your application easier to modify in the future without running into issues. Each of these different groups has a different responsibility when it comes to the application and how requests are handled.
The view consists of the parts of your application that your user will see and interact with. It is not very smart, only outputting the information given to it by the controller. The view helps users make sense of the logic behind your application and interface with it.
The model is the opposite, dealing with all the logic and data manipulation behind wheels of your application. The model responds to requests by processing any data in the necessary ways and giving it back to the controller in a form the view can understand.
The controller handles the communication and interaction of these two. When a request is put in through the view, the controller brings this to the model, and takes the model’s output back to the view to be displayed. It is a middleman that helps connect the two other layers of responsibility.
The Model-View-Controller design pattern seems like a pretty simple design pattern to comprehend. All of the components are divided by responsibility and the program is written with this in mind, making sure that only certain components handle tasks that are within their category. In terms of our projects, the front-end would amount to the view and the back end to the model, with the typescript file functioning as the model. It seems like the development of web applications would sort of naturally fall into this design pattern.
The article How to Conduct Effective Code Reviews by Billie Cleek covers code reviews, when to use them, and what your objectives and goals should be when working on or submitting a code review. He discuses the different roles you can take in a code review (which are almost analogous to our roles in two of my classes this semester) and what you should expect to do while in those roles in the process of a code review.
A code review is basically a conversation between developers on a proposed set of changes to a project. It can be a discussion about why a certain part of the code is the way it is, whether or not something is effective, or if certain changes need to be made and how to go about that. Code review boils down to having a constructive conversation regarding the development of your project, and what changes might need to be made.
I personally have had a lot of trouble communicating difficulties and voicing my opinion in past classes. It is hard to find your voice and be confident, stating the issues you see and opening yourself to feedback, however through code reviews everyone who participates stands to gain knowledge from their peers as well as experience in effectively communicating to your colleagues. As long as you are able to give and receive feedback in a helpful but constructive manner, you can help clean up a project, fixing errors and making it clear and understandable for viewers to read.
In a way, I feel like my software classes this year have done a lot of work in preparing me for being effective in code reviews, as well as in the workplace in general. A lot of the important skills in code reviews are just as important in group work: effective communication, making sure questions are answered, and mutually agreeing on the decisions being made are all essential to having an effective and useful code review. Building these skills in general will make you a better team member, and help you work better in a group on big projects.