Downloaded from git.ir
[Music]
so what is automated testing is it a
replacement for manual testing do I
really need it how should I do it should
I write my tests first which we call
test-driven development or TDD or should
I write the application code first
maash I don't know what to test these
are frequently asked questions about
automated testing and in this course I'm
gonna answer all these questions one by
one so let's start with the first
question what is automated testing
automated testing is the practice of
writing code to test our code and then
run those tests in an automated fashion
so with automated testing our source
code consists of application code which
we also call production code and test
code here's an example imagine you have
this function somewhere in your code
it's a basic calculate function that
takes an input and depending on some
conditions
it returns different values if you want
to test this function manually you have
to launch your application in the
browser perhaps you have to login or
maybe you have to do a few clicks here
and there to get to a page where this
function is used then you'll have to
fill out a form submit it and see the
result of this function on the screen
and then you have to repeat all these
steps each time using different values
in your form as you can see this is very
time consuming this workflow to test
this function may take several minutes
every time now to make matters worse
this is not the only function in your
application in a real application you
have tens or hundreds of functions like
this as your application grows in size
and complexity the time required to
manually test all the different bits and
pieces increases exponentially so that's
why we use automated testing with
automated testing you write code and
directly call this function with
different inputs and verify that this
function returns the right output now
you can rerun these tests every time you
change your
every time you commit your code to a
repository and before deploying your
application with this approach you can
test all the execution paths in this
function in less than a second you can
write several hundreds or thousands of
automated tests for various parts of
your application and run them all in
just a few seconds but there are more
benefits to automated testing and that's
the topic for the next lecture
recently a student of mine asked me
maash why on earth should be write code
to test our code when we can just run
the application and see the result well
in the last lecture you'll learn that
with automated tests you can test your
application code on a frequent basis and
in less time but this is not the only
benefit of automated testing the most
important benefit is that you can catch
the bugs before deploying your
application and this is extremely
important because it allows you to
deploy your application with more
confidence have you been in a situation
where you finish all the work deploy
your application left the office
thinking everything is working and then
got a call from your boss or an end user
telling you that one of the major
functions of the application is not
working then you had to go back to the
office and you thought that was a quick
fix but you ended up staying there until
midnight that's why you should write
tests to reduce the number of bugs that
will go into production now note that
I'm not saying that with automated tests
you're gonna release bug free software
that's not true but you can certainly
reduce the number of bugs and improve
the quality of your software another
benefit of automated tests is that they
allow you to refactor your code with
confidence
refactoring means changing the structure
of your code without changing its
behavior if you extract a few lines of a
method into a separate private method
that's refactoring if you rename a
method that's refactoring too you're
changing the structure of your code to
make it cleaner and more maintainable
but you're not changing the
functionality when you don't have
automated tests every time you refactor
your code you have to manually test
every part of the application that could
be affected by your refactoring and this
is very painful because first of all
it's time consuming and second as your
application grows you may forget about
the parts that need to be tested with
automated tests
you refactor your code you run your
tests and make sure you didn't break
anything that used to previously work
and finally another benefit of writing
tests is that it helps you focus more on
the quality of the methods you're
writing you make sure that every method
works with different inputs under
varying circumstances next I'm going to
talk about different types of tests in
automated testing we have three types of
tests unit tests integration tests and
end-to-end tests a unit test is what I
showed you earlier in this section you
test a unit of the application without
its external dependencies such as files
databases message queues web services
and so on now note this key word here
external dependencies this is really
important as you will find out shortly
so these unit tests exercise your code
without any external dependencies they
are cheap to write and they execute fast
so you can run hundreds of them in just
a few seconds and this way you can
verify that each building block in your
application is working as expected
however since you are not testing these
classes or components with their
external dependencies you can't get a
lot of confidence in the reliability of
your application so that's when
integration tests come to the rescue an
integration test tests a class or a
component with its external dependencies
so it tests the integration of your
application code with these concrete
dependencies like files databases and so
on again note that I'm emphasizing the
word external here these tests take
longer to execute because they often
involve reading or writing to a database
but they give you more confidence in the
health of your application now
traditionally an integration test is
defined as a test that takes a few units
or classes
and test their behavior as a whole so
based on this definition if you test two
classes together
some people believe you're writing an
integration test and not a unit test
even if none of these classes talk to an
external resource like a database
chances are you've heard this definition
before now I tell you what this
definition is a great recipe for writing
fragile tests that are coupled to your
implementation detail so as you change
the implementation of your classes these
tests are gonna break and you will end
up wasting a lot of time fixing them not
only won't they give you any values but
they actually slow you down I'm going to
show you an example of this later in the
course when I talk about fakes and mocks
if you have done unit testing before and
failed chances are you follow this
definition so once again a unit test
tests a class or multiple classes
without their external dependencies they
test a unit of work an integration test
tests a class or multiple classes with
their external dependencies we also have
another type of test called end to end
test that drives an application through
its user interface there are specific
tools built for creating end-to-end
tests one popular tool that you might
have heard of is selenium which allows
us to record the interaction of a user
with our application and then play back
and check if the application is
returning the right result or not these
tests give you the greatest amount of
confidence about the health of your
application but they have two big
problems the first problem is that
they're very slow because they require
launching the application and testing it
through the UI so every test is going to
launch the application potentially log
in navigate to an internal page submit a
form and inspect the results very slow
the second problem is that there are
very brittle because a small enhancement
to the application or a small change in
the user interface can easily break
these tests
[Music]
so now you know about the different
kinds of automated tasks unit tests
integration tests and end-to-end tests
but what kind of tests should you write
in your application for hell all of them
this is what we call the test pyramid
this pyramid argues that most of your
tests should be in the category of unit
tests because these tests are easy to
write and they execute quickly but since
they don't give you much confidence
about the health of your application you
should have a bunch of integration tests
that test the integration of your
application code with its external
dependencies these tests provide many
advantages of end-to-end tests but
without the complexities of dealing with
the user interface and finally you
should write very few end-to-end tests
for the key functions of the application
but you should not test the edge cases
with these end-to-end tests you only
test the happy path and leave the edge
cases your unit tests now
this pyramid is just a guideline it's
not a hard and fast rule that you need
to follow in every application the
actual ratio between your unit
integration and end-to-end tests really
depends on your project unit tests are
great for quickly testing the logic like
conditional statements and loops if you
have methods with complex logic and
calculation you should test them with
your unit tests earlier in the section I
showed you an example of a calculate
function unit tests are ideal for
testing these functions because you can
quickly test all the execution paths of
these functions in less than a second
manually testing this functions through
the user interface takes significant
amount of time and is prone to errors
however not every application has
complex logic and functions like our
calculate function you might have an
application that simply reads some data
from or writes it to a database in that
case you may need more integration tests
than unit tests so in summary this test
pyramid gives you three recommendations
first is to favour unit tests over a Qi
or end-to-end tests because these unit
tests are the fastest to run and
cheapest to write and they're very
precise so they can pinpoint exactly
where something fails they give you
rapid feedback second is to cover unit
test gaps with integration tests and
finally use end-to-end tests sparingly
only for the key functions of your
application the right balance is
different for each project on each team
at the end of the day you need to use
your own judgment to determine what kind
of test you need to write for different
parts of your application
- right unit and integration tests you
need a testing framework there are
several testing frameworks out there but
the most popular ones are an unit which
is one of the earliest frameworks out
there we've got m/s test which is
Microsoft's testing framework built into
Visual Studio and X unit which has
gained more popularity over the past
couple of years
all these frameworks give you a utility
library to write your tests and a test
runner which runs your tests and gives
you a report of passing and failing
tests which framework is better it
depends who you ask and what their
definition of better is different people
love different tools so here's my
suggestion don't get hung up on the
tooling in this course our focus is on
the fundamentals of writing quality
tests that give you value that's what
matters you can always use a different
framework as you move from one project
or team to another in this course we're
gonna start with MS test because that's
built into Visual Studio and doesn't
require any additional steps but shortly
after I'm gonna show you how to install
and unit and run annually tests in
Visual Studio you may use either of
these frameworks as purely your personal
decision
but for the majority of this course I'll
be using an unit because it has a longer
history than MS tests and I personally
find it a more elegant testing framework
now an optional tool that I highly
recommend is resharper because it has a
faster and more powerful test runner
than the one built into Visual Studio
just to let you know
resharper is a commercial product and
I'm not their affiliate you may decide
to buy a license or not that's entirely
your choice what I want to emphasize is
that you do not need resharper to write
or run tests but I use resharper because
it's a huge productivity booster another
optional tool is writer if you like
Visual Studio plus resharper but you
think Visual Studio is too slow for you
then
highly recommend you to try writer
writer is basically a cross-platform IDE
built by JetBrains the same company that
has made resharper so you have a super
fast IDE plus resharper with the exact
same shortcuts that you use in Visual
Studio in this course I'm gonna record
the first few videos with Visual Studio
because that's the default IDE for
maturity of you but later I'm gonna
switch to writer because that's a lot
faster you can use Visual Studio with or
without resharper that's perfectly fine
your focus should be on the fundamentals
of writing good tests and not the Thule
in the next lecture you're going to
write your first unit test so download
the zip file I have attached to this
lecture this is a visual studio solution
that includes some code you're going to
test throughout this course
hi guys maash here I hope you're having
a fantastic day or night wherever you
are in the world this tutorial you've
been watching is actually part of my
complete unit testing course for c-sharp
developers and what you see here on
YouTube is actually only the first
section of this course the complete
course includes more than five hours of
high quality content with plenty of
exercises and challenges that will help
you really master unit testing in case
you're interested to enroll in the full
course I've put the link for you in the
video description and if not that's
perfectly fine continue watching as the
next section is coming up
all right in the slingshot you're gonna
write your first unit test so here we
have this project called test ninja that
I'm gonna use throughout this course I
give you the link to this project in the
last lecture but if you miss that you
can see it attached to this lecture so
here we have this folder fundamentals
let's take a look at this reservation
class so imagine you're building an
application for reserving a table at a
restaurant our reservation class has
currently one property which specifies
the user who made this reservation now
in a real-world application this class
can have many other properties but we
don't want to get distracted with too
much detail this is the method we want
to test can be cancelled by a given user
so here I have implemented a simple
business rule if the user is admin or
the user who made this reservation they
can cancel this reservation otherwise
they can't cancel this reservation ok
and if you scroll down you can see our
user class very simple with one property
is admin so let's go ahead and write the
first unit test for this method here in
the solution Explorer I'm gonna add a
new project to the solution so add new
project under installed visual c-sharp
test you should see this template unit
test project if you don't see it here
chances are you have not installed
Visual Studio property so go ahead and
download the latest version of Visual
Studio currently I'm using Visual Studio
2017 Community Edition so here we select
unit test project and we give it a name
so the name of our main project is test
ninja and I'm gonna call this project
test ninja dot unit tests this is the
convention we follow to organize our
test projects we want to separate the
unit tests and integration tests because
unit tests run
quickly whereas integration tests take
more time we want to separate them so we
can run unit tests more frequently and
integration tests before committing our
code to a repository okay let's go ahead
so Visual Studio creates this new
project and you can see here we have a
file unit test one is a simple C sharp
class that has the test class attribute
and it has one method called test method
one with this attribute test method
these two attributes you see here belong
to m/s test framework so the test Runner
we have in Visual Studio looks at all
the classes decorated with the test
class attribute then it looks at all the
methods in this class decorated with the
test method attribute and it will run
them so the first thing I want to do
here is change the name of this class so
press ctrl R and then R again now you
can rename these I'm gonna call this
reservation tests because we are testing
the reservation class so the convention
we follow is the name of the class +
tests enter now similarly I'm gonna
rename this method once again ctrl R & R
the method I wanna test is can be
canceled by now here we add an underline
we specify a scenario on the line again
and expected behavior what is this let's
go back to our reservation class when
write two unit tests for this method we
want to test all the scenarios what
scenarios do we have here we have three
scenarios one scenario is when the user
is an admin the other scenario is when
the user is the same person who made
this reservation and the third scenario
is when someone else tries to cancel
this reservation so here we have three
scenarios or three execution paths so
there are three ways to get out of this
method that's why we call this three
execution paths okay so back to our unit
test class the first scenario we want to
test is user is admin now what is the
expected behavior if the user is admin
this method should return true
so returns true this is the convention
we use to name and organize our test
methods every test method has three
parts the first part specifies the name
of the method under test the second part
is the scenario we're testing and the
third part is the expected behavior now
inside every test method we have three
parts
a range act and assert this convention
is called triple-a or arranged act and
assert the arranged part is where we
initialize our objects we prepared the
object we want to test in this case we
want to create an instance of the
reservation class so we create a
reservation object new reservation now
here the reservation class is not
recognized so you need to press ctrl +
period and in this context menu select
add reference to test ninja okay so we
have a reservation object the act part
is where we act on this object and that
basically means we're gonna call a
method that's the method we're going to
test in this case reservation dot can be
cancelled by now I want to give it an
argument in this case we want to give it
a user that is an admin user so here I
create a user object and set is admin to
true so this is the act part now we want
to get the result and verify that it's
correct so I'm gonna store the result in
a variable called result and in the
assert part we verify that result is
correct in this case result should be
true so here I'm gonna use one of the
helper classes in Emma's test framework
that is called assert this class has a
bunch of static methods that we use to
make an assertion for example if you
want to compare two objects we can use
are equal we also have other methods
here like is false is instance of type
is not instance of type and so on so
here we want to assert that this result
is true so we call assert dot is true
and pass result so this is how we write
a unit test now to run this test we go
on the top from the test menu go to run
and select all tests this is what I
don't like about Visual Studio because
here we don't have the ability to run
only a particular test method like this
test method we wrote in this lecture we
can only run all the tests in this
project and that's why I like resharper
because with resharper I can run only
this test or I can run all the tests in
this class so it's more flexible I'm
going to show you that later in this
section so let's go on the top from the
test menu run all tests and note this
shortcut remember this so you can
quickly run all your tests
they should open this text explorer
window if you don't see that you can
find it on the top under test windows
test explorer okay
so you can see we have a passing test we
have a green mark you can see the name
of our test method and the time it took
to run this test in a real world
application you're gonna have hundreds
or thousands of unit tests so when you
run your tests
this window is going to be populated
with all the tests in your application
now let me show you an example of a
failing test so I'm going to go back to
the reservation class and create a bug
in our code so here I'm going to return
false let's say the developer who wrote
this code made this mistake
as I told you before with unit tests we
can catch bugs before deploying our
application so when we create a unit
test class and verify the expected
behavior of a method in this case you're
verifying that this method is returning
true with this unit test we can catch
bugs earlier and the software
development lifecycle
so back to our test Explorer window I'm
going to run all the tests again
this time our test failed so you can see
the benefit of unit tests in action now
here is an exercise for you as I told
you before this method has three
execution paths or three scenarios I
want you to use what you learn in this
lecture and write the other 2 unit tests
for this method in the next lecturer
you're going to see my solution
in the last lecture we renamed this
class to reservation tests but
apparently the rename refactoring
feature in Visual Studio didn't work
properly because the name of the file is
still unit test 1 so I'm gonna rename
this to reservation tests dot CS with
this convention you can easily find all
the tests for a given class ok
beautiful now that's right the second
unit test so I'm gonna write a public
void method and by the way all your test
methods should be public void so here
we're gonna use our convention to call
this method the first part is the method
on the test that is can be canceled by
the second part is the scenario so let's
say we want to test the scenario where
the same user who made the reservation
wants to cancel this reservation so same
user canceling the reservation now the
third part is the expected behavior what
do we expect this method to return you
should return true ok now inside this
method we should have three parts
arrange act and assert in the last
lecture I added comments to separate the
arranged act and assert parts but in a
real world scenario you don't
necessarily have to do this if your test
method is short and clean so in the
arrange part I'm going to create a new
reservation object so reservation it's a
new reservation in the act
I'm gonna call reservation can be
canceled by now here I want to simulate
a scenario where the same user is
canceling this reservation so I'm gonna
create a user object here
you
and first of all set the made by
property to this user so this user
created this reservation before now I
want to pass the same user object as an
argument to this method user now we get
the result and store it I finally make
an assertion so we assert that result is
true so now with these vertical spaces I
have added in the code you can see the
arrange the act and assert parts back in
our test Explorer window
let's run all the tests so we have one
failing test and this is because in the
last lecture I created a bug in our code
so let me change this here we return
true now back to our test class this new
method I created here is not picked up
by test Explorer we don't see that here
why because we forgot to decorate it
with the test method attribute so that's
why you should decorate every test
method with this attribute so it can be
picked up by the test runner now save
back in test Explorer run all now we
have to passing tests beautiful now
let's write the last test so I'm gonna
start with test method and public void
can be canceled by the third scenario is
a user trying to cancel someone else's
reservation so another user canceling
reservation what is the expected
behavior this method should return false
so return false
once again in the orange part I'm going
to create a reservation object new your
reservation and the act part we call can
be cancelled by now here we want to deal
with two different user objects so here
I can pass a user object and when
initializing the reservation I can set
made by two different user object and
finally we need to store the result here
and assert that result is false so is
false result now let's run all the tests
so we have three passing tests beautiful
so I have renamed this test method to
make them more consistent and easier to
read so we have three scenarios admin
canceling same user canceling and
another user canceling one thing you can
see about these tests is that they act
as some kind of documentation about our
source code this is another benefit of
writing tests imagine you join a new
team they give you a new project and
your task is to make some modifications
to a class if that class is properly
supported by a bunch of JUnit tests you
can easily figure out what the
responsibility of that class is now let
me show you another benefit of writing
tests earlier in this section I told you
that once you have tests you can
refactor your code with confidence so
back in our reservation class I don't
like the way this method is implemented
it looks very amateurish so I'm gonna
refactor it and then run all my tests
and see if I've broken anything or not
so the first change I wanna make here is
instead of having two if statements I'm
gonna have one if statement and use the
logical or operator so if user is admin
or made by equals user we're gonna
return true otherwise we're gonna return
false now back in test Explorer run all
the tests so my tests are verifying that
our application is still working I have
not broken anything I can take this to
the next level so instead of having this
if statement here and then return false
I'm simply gonna return the result of
this expression now we have only one
line of code here once again we run all
the tests all the tests are passing
our code is much cleaner and you can see
another benefit of writing tests
so far you have seen Emma's test in
action in this lecture I'm going to show
you how to use an unit which is my
preferred testing framework so an unit
is not part of Visual Studio and if you
want to use it you need to install a
couple of NuGet packages so open a
package manager console make sure to
select test ninja that unit tests and
the project drop down list now we need
to install a couple of packages so
install - package
the first one is any unit and make sure
to set the version to the same version
that I'm gonna use in this video so you
will have the same experience so -
version three point eight point one
beautiful now the second package install
package and unit three test adapter we
need this package to run and unit tests
inside visual studio because by default
the test runner that is built into
Visual Studio only recognizes MS tests
so set the version here as well this one
is three point eight point zero so it's
not exactly the same version as any unit
because these two packages are developed
independently but these two versions are
compatible okay beautiful now with n
unit we have different attributes so
instead of test class we use test
fixture now we need to import this type
so press ctrl + period and select the
first item using n unit dot framework
okay and instead of test method we have
test
like this and finally we need to modify
how we make assertions so here we have a
compilation error because Visual Studio
doesn't know whether we're referring to
the assert class in any unit framework
or MS test so I'm going to go on the top
and remove this using statement for
importing Microsoft unit testing
framework so delete the compilation is
gone so you can see this assert class
has the same API as the assert class in
MS test but here we have a different way
of writing assertions which is more
readable so another way to write the
same assertion is like this assert that
result is true it reads like plain
English also another way is to write
assert that result equals true so we can
add a boolean expression here which I
approach you choose is purely your
personal preference there is no
technical differences between these
three ways of making assertions so in
this lecture I'm gonna use the second
for delete and delete all right now
let's run these tests so once again on
the top test run all tests
so all tests are passing beautiful so
this is how you use any unit inside
Visual Studio now if you use resharper
you don't need to install and unit test
adapter because the test runner that
comes with resharper automatically picks
and unit tests the same is true if you
use the writer ID
when you get started with automatic
testing a word that you hear often is
test-driven development or TDD
test-driven development or TDD also
called test first is an approach to
build software with TDD you write your
tests before writing the application or
production code the first time I heard
this I asked how on earth is that even
possible how can we test the code that
we haven't written chances are have the
same question so let's see how you start
by writing a failing test this test
should fail because you don't have any
application code that would make it pass
right then you'll write the simplest
application code that will make this
test pass the absolute simplest you
don't want to over engineer here you
don't want to design a class diagram
with a zillion classes and methods use
the simplest implementation that would
make the test pass then refactor your
code if necessary these three steps are
the foundation of TDD you repeat these
three steps over and over until you
build a complete feature now what is so
special about TDD well first is that
your source code will be testable right
from the get-go you don't have to make
any changes your code to make it
testable second is that every line of
your production code is fully covered by
tests which means you can refactor and
deploy with confidence and third is that
it often results in a simpler
implementation when you start with a big
class diagram chances are you're
over-engineering and making the solution
more complex if you write enough code to
make all the tests pass and that
solution works there is no reason to
write more code the fact that all your
tests pass means you've fulfilled all
the business requirements so unless
there is a new requirement you don't
need to write more code and if there is
a new requirement you start by failing
tests so this is TDT in TDD we write our
tests
first and that's why we call this
approach test-driven development so our
development is driven by our tests in
contrast to TDD or tests first we have
code first which is what you have been
doing so far you start with your
application code and then you write
tests which approach is better it
depends who you ask
in theory TDD is more promising because
of the benefits I told you but in
practice sometimes it can get really
complex and it may slow you down if
that's the case it's better to switch to
the code first approach and write your
tests after in this course our focus
will be on the code first approach so we
can master the fundamentals of testing
once you master the fundamentals then
you'll be ready to start your tests
first journey TDD really requires a
separate course and I'm not going to
talk about it throughout this course but
if you're interested potentially in the
future I can create a course on
test-driven development
all right now let me give you an
overview of how I have structured this
course real quick in the next section
you're going to learn the fundamentals
of unit testing in this section we'll be
looking at characteristics of good and
trustworthy unit tests we'll be looking
at naming and organizing tests writing
some basic unit tests as well as
creating parameterised tests once you
master the fundamentals then we'll be
looking at the core unit testing
techniques in this section in each
lecture I'm going to show you an example
of a function to test each function
shows you a scenario that you see in a
lot of real-world applications the
following section is all about exercises
so in that section I will give you three
unit testing exercises and you will have
a chance to put what you learn in the
first two sections in practice for each
exercise you can see my solution as well
now up to this point all our unit tests
are four simple classes that don't have
any external dependencies but in the
real world our code often talks to a
database and web servers and so on so
section 5 is all about dealing with
these external dependencies in this
section you will learn about concepts
such as dependency injection and marking
the following section again is all about
exercises so we'll look at three
examples of code that touches an
external resource and finally the last
two sections include more challenging
exercises I will show you a snippet of
source code taken from a real project
and your job is to write all the
necessary unit tests for that code and
of course you're going to see my
solution as well
so in this section you learned about
automated testing and its benefits
Maurice pacifically you learned that it
helps you prefactor your code with
confidence and release software of
better quality and with less bugs you
learn about three types of tests unit
integration and end-to-end tests and you
also saw a glimpse of unit testing in
action you learn how to write a basic
unit test in Visual Studio and finally
you learned how to run and debug your
unit tests in the next section we're
going to look at the core techniques for
writing unit tests so I will see you in
the next section
bye guys maash here so if you made it
this far you seem to be really
enthusiastic about learning unit testing
so I highly recommend you to enroll in
my unit testing course and don't waste
your time jumping from one tutorial to
another when you enroll you will learn
everything about unit testing from A to
Z and by the end of watching the course
you'll also get a certificate of
completion which you can present your
current or future employers so the link
to the full course is in the video
description I hope to see in the course