- When we write software,
we're communicating with more than just computers.
Of course, computers interpret and execute our code
which consists of instructions and rules.
People, including the codes author and maintainers
read and write code.
In this case, the code describes the intent of the software.
When the code is read, people should understand what, why
and how the software works.
Needless to say, software engineers have a daunting task.
They need to communicate their intent and goals
to both people and computers.
Everyone and everything involved needs to understand
each other.
As you can imagine, things don't always go according
to plan and mistakes happen.
Of course, each audience handles errors in their own way.
Humans by very nature make mistakes and adapt in response.
If you've ever watched a speech or a live music performance
you've seen a few little mistakes.
Using context and experience we unconsciously accept
and correct mistakes on.
The mistakes are forgotten and the content is remembered.
In comparison, computers literally interpret
what we tell them to do.
A mistake and syntactically correct instructions
will be dutifully executed.
For example it, computer to store an email address,
then give it a picture of a fish.
Unless there are validation rules saying that images
aren't allowed, the computer will happily store the fish.
This course's goal is to improve communication
between software engineers and computers.
In this chapter, we're going to be defining core concepts
and theory around both testing and code quality.
I'll introduce each concept,
then apply that knowledge throughout.
We'll start with the abstract question.
What is code quality?
Next, we'll take a look at coding standards
and how to enforce them.
We'll define unit testing, Test Driven Development
and Behavior Driven Development
then compare the differences.
We'll take a look at the role of testing frameworks
and why they're important.
Finally, we'll see how assertion libraries verify
how correct your programs are.
So, what is code quality?
Let's define what quality is first.
Joseph M. Juran's quality control handbook defines quality
with two specific meanings.
Quality consists of those product features
that meet the needs of customers
and thereby provide product satisfaction.
And, quality consists of freedom from deficiencies.
Code quality builds on those concepts in many different
but related ways.
Quality code meets the functional requirements,
meaning it does what it's supposed to do.
Let's use example of email storage.
The requirements are the ability to store an email address.
There are two parts of this requirement.
If the code written couldn't store an email address,
then it would fail the storage required.
If you could store a picture of a fish
that is not an email address and the requirements
are not met.
Quality code is free from deficiencies.
Which means no failings or shortcomings.
These can be broadly generalized in two ways,
usefulness and maintainability.
Let's explore each.
What is useful code?
The more flexible and reusable the code is,
the more useful it is.
For example, you can write a function that takes a number,
adds one to it and returns the result.
That may fulfill the functional requirement,
but it's inflexible.
We could improve upon it by adding any number to any number
which would be more useful.
Of course, you should use the programming languages
built in math library.
That would be the most useful and flexible overall.
What about maintainable code?
There are three questions that can determine
if code is maintainable or not.
The first is can you personally maintain the code?
The next step is, can someone else maintain
it without asking for help?
Finally, can someone else read the code
and understand the design and intent?
If the answer to all three questions is yes,
then the code is maintainable.
Maintainable code is not an absolute.
Instead, it evolves over the life cycle of the software.
Code may start as unmaintainable and improve over time.
On the other hand, sloppy and inconsistent changes
may make it worse over time.
Engineers improve with experience.
So, revisiting old code will make you want to clean it up.
The goal should be continual, gradual improvement
Is best make a series of incremental improvements
rather than a radical overhaul.
That way, you reduce the risk of damaging functional code
that was otherwise working without a problem.
We now know the questions to ask to determine
if code is maintainable.
What's the most certain way to decide
if code meets those standards
Peer review.
Where another person reads your code and documentation.
If they can understand the design and intent,
then the code is maintainable.
You can take steps to improve the maintainability
of your code.
For example, the use of consistent formatting
and logical naming helps other people read it.
The code should include clear and appropriate comments
along with functional documentation
that describes the intent.
Using appropriate modularization into atomic components
makes the code usable.
Like watching a musician or an athlete,
the result of hard work and practice can look effortless.
Should every piece of code that you write
be high quality?
We should always strive for excellence,
but be reasonable at the same time.
Sometimes a one-off script to perform a single task
can be necessary.
You should still document what it's doing,
why it was needed and when.
It sounds complicated, but a quick code comment and a commit
to the source code tracking system can be enough.
Chances are that you may need to refer to it again
or reuse some of the functionality elsewhere.
In summary, the phrase code quality has several meanings.
Foremost, it should meet functional requirements.
Quality code should be maintainable by yourself
and by others.
Finally, it should be useful in multiple places
even in different programs.
There are many ways to measure and ensure code quality.
The first most basic, is the use of a coding standard.
What's a coding standard?