SlideShare a Scribd company logo
1 of 149
Download to read offline
Structure and
Interpretation
of Test Cases
@KevlinHenney
Programs must be
written for people to
read, and only
incidentally for
machines to execute.
Write Tests for People
Gerard Meszaros
So who should you be writing the
tests for? For the person trying to
understand your code.
Good tests act as documentation
for the code they are testing.
Gerard Meszaros
Very many people say "TDD"
when they really mean, "I have
good unit tests" ("I have GUTs"?).
Alistair Cockburn
The modern programming professional has GUTs
good unit tests" ("I have GUTs
A unit test is a test of behaviour
whose success or failure is wholly
determined by the correctness of
the test and the correctness of
the unit under test.
Kevlin Henney
https://www.theregister.co.uk/2007/07/28/what_are_your_units/
Unit testable
Necessarily not unit testable
Should be unit testable... but isn’t
The programmer in me made unit testing more
about applying and exercising frameworks.
I had essentially reduced my concept of unit
testing to the basic mechanics of exercising
xUnit to verify the behavior of my classes.
My mindset had me thinking far too narrowly
about what it meant to write good unit tests.
Tod Golding
Tapping into Testing Nirvana
about what it meant to write good unit tests
From time to time I hear people
asking what value of test coverage
(also called code coverage) they
should aim for, or stating their
coverage levels with pride.
Such statements miss the point.
Martin Fowler
http://martinfowler.com/bliki/TestCoverage.html
I expect a high level of coverage.
Sometimes managers require one.
There's a subtle difference.
Brian Marick
http://martinfowler.com/bliki/TestCoverage.html
public static bool IsLeapYear(int year) 
[Test]
public void Test() 
[Test]
public void TestIsLeapYear() 
[Test]
public void TestIsLeapYearIsCorrect() 
[Test]
public void Test1() 
[Test]
public void Test2() 
[Test]
public void TestLeapYears() 
[Test]
public void TestNonLeapYears() 
[Test]
public void TestLeapYears()
{
Assert.IsTrue(IsLeapYear(2016));
Assert.IsTrue(IsLeapYear(2000));
}
[Test]
public void TestNonLeapYears() 
[Test]
public void Test2016IsALeapYear() 
[Test]
public void Test2000IsALeapYear() 
[Test]
public void Test2018IsNotALeapYear() 
[Test]
public void Test1900IsNotALeapYear() 
[Test]
public void _2016IsALeapYear() 
[Test]
public void _2000IsALeapYear() 
[Test]
public void _2018IsNotALeapYear() 
[Test]
public void _1900IsNotALeapYear() 
[Test]
public void _2016_is_a_leap_year() 
[Test]
public void _2000_is_a_leap_year() 
[Test]
public void _2018_is_not_a_leap_year() 
[Test]
public void _1900_is_not_a_leap_year() 
_2016_is_a_leap_year
_2000_is_a_leap_year
_2018_is_not_a_leap_year
_1900_is_not_a_leap_year
_2020_is_a_leap_year
_2400_is_a_leap_year
_2019_is_not_a_leap_year
_2100_is_not_a_leap_year
Years_divisible_by_4_are_leap_years
Years_divisible_by_400_are_leap_years
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_100_are_not_leap_years
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_are_leap_years
Years_divisible_by_100_are_not_leap_years
Years_divisible_by_400_are_leap_years
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_but_not_by_100_are_leap_year
Years_divisible_by_100_but_not_by_400_are_not_lea
Years_divisible_by_400_are_leap_years
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_but_not_by_100_are_leap_years
Years_divisible_by_100_but_not_by_400_are_not_leap_years
Years_divisible_by_400_are_leap_years
IsLeapYear_YearNotDivisibleBy4_ReturnsFalse
IsLeapYear_YearDivisibleBy4ButNotBy100_ReturnsTrue
IsLeapYear_YearDivisibleBy100ButNotBy400_ReturnsFalse
IsLeapYear_YearDivisibleBy400_ReturnsTrue
Propositions
are vehicles
for stating
how things are
or might be.
Thus only indicative
sentences which it
makes sense to think
of as being true or as
being false are
capable of expressing
propositions.
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_but_not_by_100_are_leap_years
Years_divisible_by_100_but_not_by_400_are_not_leap_years
Years_divisible_by_400_are_leap_years
public static bool IsLeapYear(int year)
{
return
year % 4 == 0 &&
year % 100 != 0 ||
year % 400 == 0;
}
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_but_not_by_100_are_leap_years
Years_divisible_by_100_but_not_by_400_are_not_leap_years
Years_divisible_by_400_are_leap_years
public static bool IsLeapYear(int year)
{
return year % 4 == 0;
}
Years_not_divisible_by_4_are_not_leap_years
Years_divisible_by_4_but_not_by_100_are_leap_years
Years_divisible_by_100_but_not_by_400_are_not_leap_years
Years_divisible_by_400_are_leap_years
For tests to drive development they must
do more than just test that code performs
its required functionality: they must clearly
express that required functionality to the
reader.
That is, they must be clear specifications
of the required functionality.
Nat Pryce & Steve Freeman
Are your tests really driving your development?
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100() 
[Test]
public void if_it_is_divisible_by_400() 
}
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4() 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100() 
[Test]
public void if_it_is_divisible_by_400() 
}
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4() 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(IsLeapYear(2018));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400()
{
Assert.IsFalse(IsLeapYear(1900));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(isLeapYear(2018));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400()
{
Assert.IsFalse(isLeapYear(1900));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(isLeapYear(42));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400()
{
Assert.IsFalse(isLeapYear(100));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4()
{
Assert.IsFalse(IsLeapYear(2018));
Assert.IsFalse(IsLeapYear(2017));
Assert.IsFalse(IsLeapYear(42));
Assert.IsFalse(IsLeapYear(1));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[TestCase(2018)]
[TestCase(2017)]
[TestCase(42)]
[TestCase(1)]
public void if_it_is_not_divisible_by_4(int year)
{
Assert.IsFalse(IsLeapYear(year));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4(
[Values(2018, 2017, 42, 1)] int year)
{
Assert.IsFalse(IsLeapYear(year));
}
[Test]
public void if_it_is_divisible_by_100_but_not_by_400() 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100(
[Values(2016, 1984, 4)] int year) 
[Test]
public void if_it_is_divisible_by_400(
[Range(400, 2400, 400)] int year) 
}
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4(
[Values(2018, 2017, 42, 1)] int year) 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400(
[Values(2100, 1900, 100)] int year) 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year
{
[Test]
public void if_it_is_divisible_by_4_but_not_by_100(
[Values(2016, 1984, 4)] int year) 
[Test]
public void if_it_is_divisible_by_400(
[Range(400, 2400, 400)] int year) 
}
[TestFixture]
public class A_year_is_not_a_leap_year
{
[Test]
public void if_it_is_not_divisible_by_4(
[Values(2018, 2017, 42, 1)] int year) 
[Test]
public void if_it_is_divisible_by_100_but_not_by_400(
[Values(2100, 1900, 100)] int year) 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year
{
[Test]
public void is_either_a_leap_year_or_not([Range(1, 10000)] int year) 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year
{
[Test]
public void is_either_a_leap_year_or_not([Range(1, 10000)] int year) 
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year
{
[Test]
public void is_either_a_leap_year_or_not([Range(1, 10000)] int year)
{
Assert.AreEqual(
year % 4 == 0 && year % 100 != 0 || year % 400 == 0,
IsLeapYear(year));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year
{
[Test]
public void is_either_a_leap_year_or_not([Range(1, 10000)] int year)
{
Assert.AreEqual(LeapYearExpectation(year), IsLeapYear(year));
}
public static bool LeapYearExpectation(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
}
}
public static bool IsLeapYear(int year)
{
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
All happy families are alike;
each unhappy family is
unhappy in its own way.
Leo Tolstoy
Anna Karenina
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year 
[TestFixture]
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Throws<ArgumentException>(() => IsLeapYear(0));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year 
[TestFixture]
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Catch<ArgumentException>(() => IsLeapYear(0));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year 
[TestFixture]
public class A_year_is_not_supported
{
[Test]
public void if_it_is_0()
{
Assert.Catch<ArgumentException>(() => IsLeapYear(0));
}
[Test]
public void if_it_is_negative(
[Values(-1, -4, -100, -400)] int year)
{
Assert.Catch<ArgumentException>(() => IsLeapYear(year));
}
}
}
namespace Leap_year_spec
{
[TestFixture]
public class A_year_is_a_leap_year 
[TestFixture]
public class A_year_is_not_a_leap_year 
[TestFixture]
public class A_year_is_supported
{
[Test]
public void if_it_is_positive(
[Values(1, int.MaxValue)] int year)
{
Assert.DoesNotThrow(() => IsLeapYear(year));
}
}
[TestFixture]
public class A_year_is_not_supported 
}
Stack
{new, push, pop, depth, top}
An abstract data type defines a
class of abstract objects which
is completely characterized by
the operations available on
those objects.
Barbara Liskov
Programming with Abstract Data Types
 T •  Stack
{
new: Stack[T],
push: Stack[T]  T → Stack[T],
pop: Stack[T] ⇸ Stack[T],
depth: Stack[T] → Integer,
top: Stack[T] ⇸ T
}
template<typename T>
class stack
{
public:
stack();
void push(const T & new_top);
void pop();
std::size_t depth() const;
T top() const;
private:
...
};
TEST_CASE(“test stack::stack”) 
TEST_CASE(“test stack::push”) 
TEST_CASE(“test stack::pop”) 
TEST_CASE(“test stack::depth”) 
TEST_CASE(“test stack::top”) 
TEST_CASE(“stack tests”)
{
SECTION(“test constructor”) 
SECTION(“test push”) 
SECTION(“test pop”) 
SECTION(“test depth”) 
SECTION(“test top”) 
}
TEST_CASE(“stack tests”)
{
SECTION(“constructor”) 
SECTION(“push”) 
SECTION(“pop”) 
SECTION(“depth”) 
SECTION(“top”) 
}
template<typename T>
class stack
{
public:
stack();
void push(const T & new_top);
void pop();
std::size_t depth() const;
T top() const;
private:
...
};
template<typename T>
class stack
{
public:
stack() = default;
void push(const T & new_top);
void pop();
std::size_t depth() const;
T top() const;
private:
...
};
TEST_CASE(“stack tests”)
{
SECTION(“constructor”) 
SECTION(“push”) 
SECTION(“pop”) 
SECTION(“depth”) 
SECTION(“top”) 
}
TEST_CASE(“stack tests”)
{
SECTION(“push”) 
SECTION(“pop”) 
SECTION(“depth”) 
SECTION(“top”) 
}
TEST_CASE(“stack tests”)
{
SECTION(“can be constructed”) 
SECTION(“can be pushed”) 
SECTION(“can be popped”) 
SECTION(“has depth”) 
SECTION(“has a top”) 
}
TEST_CASE(“stack tests”)
{
SECTION(“can be constructed”) 
SECTION(“can be pushed”) 
SECTION(“can sometimes be popped”) 
SECTION(“has depth”) 
SECTION(“sometimes has a top”) 
}
https://twitter.com/chrisoldwood/status/918139432447954944
Given
When
Then
an empty stack
an item is pushed
it should not be empty
Given
When
Then
an empty stack
an item is pushed
if it's OK with you, I
think that, perhaps, it
should probably not be
empty, don't you think?
Make definite assertions.
Avoid tame, colourless, hesitating, noncommittal
language.
When a sentence is made stronger, it usually becomes
shorter. Thus brevity is a by-product of vigour.
William Strunk and E B White
The Elements of Style
Given
When
Then
an empty stack
an item is pushed
it must not be empty
Given
When
Then
an empty stack
an item is pushed
it is not empty
Given
When
Then
And
an empty stack
an item is pushed
it has a depth of 1
the top item is the item
that was pushed
GivenAnEmptyStackWhenAnI
temIsPushedThenItHasADep
thOf1AndTheTopItemIsTheI
temThatWasPushed
Given_an_empty_stack_Whe
n_an_item_is_pushed_Then
_it_has_a_depth_of_1_And
_the_top_item_is_the_ite
m_that_was_pushed
Given an empty stack
When an item is pushed
Then it has a depth of 1
And the top item is the
item that was pushed
An empty stack acquires
depth by retaining a
pushed item as its top
Omit needless words.
William Strunk and E B White
The Elements of Style
TEST_CASE(“Stack specification”)
{

SECTION(“An empty stack acquires depth by retaining a pushed item as its top")
{
stack<std::string> stack;
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}

}
TEST_CASE(“Stack specification”)
{
SECTION(“A new stack is empty”) 
SECTION(“An empty stack throws when queried for its top item”) 
SECTION(“An empty stack throws when popped”) 
SECTION(“An empty stack acquires depth by retaining a pushed item as its top”) 
SECTION(“A non-empty stack becomes deeper by retaining a pushed item as its top”) 
SECTION(“A non-empty stack on popping reveals tops in reverse order of pushing”) 
}
TEST_CASE(“Stack specification”)
{
SECTION(“A new stack is empty”) 
SECTION(“An empty stack throws when queried for its top item”) 
SECTION(“An empty stack throws when popped”) 
SECTION(“An empty stack acquires depth by retaining a pushed item as its top”) 
SECTION(“A non-empty stack becomes deeper by retaining a pushed item as its top”) 
SECTION(“A non-empty stack on popping reveals tops in reverse order of pushing”) 
}
TEST_CASE(“Stack specification”)
{

SECTION(“An empty stack acquires depth by retaining a pushed item as its top")
{
stack<std::string> stack;
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}

}
For each usage scenario, the test(s):
▪ Describe the context, starting point, or
preconditions that must be satisfied
▪ Illustrate how the software is invoked
▪ Describe the expected results or
postconditions to be verified
Gerard Meszaros
TEST_CASE(“Stack specification”)
{

SECTION(“An empty stack acquires depth by retaining a pushed item as its top")
{
// Arrange:
stack<std::string> stack;
// Act:
stack.push("ACCU");
// Assert:
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}

}
TEST_CASE(“Stack specification”)
{

SECTION(“An empty stack acquires depth by retaining a pushed item as its top")
{
// Arrange:
stack<std::string> stack;
// Act:
stack.push("ACCU");
// Assert:
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}

}
TEST_CASE(“Stack specification”)
{

SECTION(“An empty stack acquires depth by retaining a pushed item as its top")
{
// Given:
stack<std::string> stack;
// When:
stack.push("ACCU");
// Then:
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}

}
https://twitter.com/jasongorman/status/572829496342134784
Communications of the ACM, 12(10), October 1969
P {Q} R
If the assertion P is true before
initiation of a program Q, then
the assertion R will be true on
its completion.
{P} Q {R}
An interface is a contract to deliver a
certain amount of service.
Clients of the interface depend on the
contract, which is usually documented
in the interface specification.
Butler W Lampson
Hints for Computer System Design
template<typename T>
class stack
{
public:
stack();
void push(const T & new_top);
void pop();
std::size_t depth() const;
const T & top() const;
private:
...
};
postcondition:
depth() == 0
where:
old_depth = depth()
postcondition:
depth() == old_depth + 1 && top() == new_top
where:
old_depth = depth()
precondition:
depth() > 0
postcondition:
depth() == old_depth – 1
where:
result = depth()
postcondition:
result >= 0
precondition:
depth() > 0
template<typename T>
class stack
{
public:
stack();
void push(const T & new_top);
void pop();
std::size_t depth() const;
const T & top() const;
private:
...
};
[[expects: depth() == 0]]
[[ensures: depth() > 0]]
[[ensures: top() == new_top]]
[[expects: depth() > 0]]
[[ensures: depth() >= 0]]
[[ensures result: result >= 0]]
[[expects: depth() > 0]]
alphabet(Stack) =
{new, push, pop, depth, top}
trace(Stack) =
{⟨new⟩,
⟨new, push⟩,
⟨new, depth⟩,
⟨new, push, pop⟩,
⟨new, push, top⟩,
⟨new, push, depth⟩,
⟨new, push, push⟩,
⟨new, depth, push⟩,
⟨new, depth, depth⟩,
⟨new, push, push, pop⟩,
...}
Non-EmptyEmpty
depth depth
top
push
pop [depth > 1]
push
pop [depth = 1]
new
Non-EmptyEmpty
depth
top / error
pop / error
depth
top
push
pop [depth > 1]
push
pop [depth = 1]
new
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
SECTION("is empty") ...
}
SECTION("An empty stack")
{
SECTION("throws when queried for its top item") ...
SECTION("throws when popped") ...
SECTION("acquires depth by retaining a pushed item as its top") ...
}
SECTION("A non empty stack")
{
SECTION("becomes_deeper_by_retaining_a_pushed_item_as_its_top") ...
SECTION("on popping reveals tops in reverse order of pushing") ...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
SECTION("is empty") ...
}
SECTION("An empty stack")
{
SECTION("throws when queried for its top item") ...
SECTION("throws when popped") ...
SECTION("acquires depth by retaining a pushed item as its top") ...
}
SECTION("A non empty stack")
{
SECTION("becomes_deeper_by_retaining_a_pushed_item_as_its_top") ...
SECTION("on popping reveals tops in reverse order of pushing") ...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack<std::string> stack;
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
SCENARIO("Stack specification")
{
...
GIVEN("An empty stack")
{
stack<std::string> stack;
...
WHEN("an item is pushed")
{
stack.push("ACCU");
THEN(“acquires depth by retaining the new item as its top”)
{
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
}
...
}
SCENARIO("Stack specification")
{
...
GIVEN("An empty stack")
{
stack<std::string> stack;
...
WHEN("an item is pushed")
{
stack.push("ACCU");
THEN(“acquires depth”)
{
REQUIRE(stack.depth() == 1);
}
THEN(“retains the new item as its top”)
{
REQUIRE(stack.top() == "ACCU");
}
}
}
...
}
SCENARIO("Stack specification")
{
...
GIVEN("An empty stack")
{
stack<std::string> stack;
...
WHEN("an item is pushed")
{
stack.push("ACCU");
THEN(“acquires depth”)
REQUIRE(stack.depth() == 1);
THEN(“retains the new item as its top”)
REQUIRE(stack.top() == "ACCU");
}
}
...
}
Given can be used to group
tests for operations with
respect to common
initial state
When can be used to group
tests by operation,
regardless of initial state
or outcome
Then can be used to group
tests by common
outcome, regardless of
operation or initial state
For each usage scenario, the test(s):
▪ Describe the context, starting point, or
preconditions that must be satisfied
▪ Illustrate how the software is invoked
▪ Describe the expected results or
postconditions to be verified
Gerard Meszaros
For each usage scenario, the test(s):
▪ Describe the context, starting point, or
preconditions that must be satisfied
▪ Illustrate how the software is invoked
▪ Describe the expected results or
postconditions to be verified
Gerard Meszaros
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.items.size() == 1);
REQUIRE(stack.items[0] == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.get_items().size() == 1);
REQUIRE(stack.get_items()[0] == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.items().size() == 1);
REQUIRE(stack.items()[0] == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
TEST_CASE("Stack specification")
{
SECTION("A new stack")
{
...
}
SECTION("An empty stack")
{
stack<std::string> stack;
...
SECTION("acquires depth by retaining a pushed item as its top")
{
stack.push("ACCU");
REQUIRE(stack.depth() == 1);
REQUIRE(stack.top() == "ACCU");
}
}
SECTION("A non empty stack")
{
...
}
}
A programmer [...] is concerned
only with the behavior which
that object exhibits but not with
any details of how that behavior
is achieved by means of an
implementation.
Barbara Liskov
Programming with Abstract Data Types
template<typename T>
class stack
{
public:
std::size_t depth() const
{
return items.size();
}
const T & top() const
{
if (depth() == 0)
throw std::logic_error("stack has no top");
return items.back();
}
void pop()
{
if (depth() == 0)
throw std::logic_error("cannot pop empty stack");
items.pop_back();
}
void push(const T & new_top)
{
items.push_back(new_top);
}
private:
std::vector<T> items;
};
template<typename T>
class stack
{
public:
std::size_t depth() const
{
return size;
}
const T & top() const
{
if (depth() == 0)
throw std::logic_error("stack has no top");
return items.front();
}
void pop()
{
if (depth() == 0)
throw std::logic_error("cannot pop empty stack");
items.pop_front();
--size;
}
void push(const T & new_top)
{
items.push_front(new_top);
++size;
}
private:
std::size_t size = 0;
std::forward_list<T> items;
};
Queue
{new, length, capacity, enqueue, dequeue}
producer consumerspacetime decoupling
N
buffered
bounded
asynchronous
N =
buffered
unbounded
asynchronous
∞
N = 1
buffered
bounded
asynchronous
futurepromise
N = 0
unbuffered
bounded
synchronous
public class Queue<T>
{
...
public Queue(int capacity) ...
public int length() ...
public int capacity() ...
public boolean enqueue(T last) ...
public Optional<T> dequeue() ...
}
Non-EmptyEmpty
length
capacity
dequeue
length
capacity
enqueue
dequeue [length > 1]
enqueue
dequeue [length = 1]
new [capacity > 0]
Non-Full
Empty
length
capacity
dequeue
length
capacity
enqueue
dequeue [length > 1]
enqueue
dequeue [length = 1]
new [capacity > 0]
Full
Non-Empty
[length = capacity]
[length < capacity]
public class Queue_spec 
public class A_new_queue 
public void is_empty() 
public void preserves_positive_bounding_capacity(int capacity) 
public void cannot_be_created_with_non_positive_bounding_capacity(int capacity) 
public class An_empty_queue 
public void dequeues_an_empty_value() 
public void remains_empty_when_null_enqueued() 
public void becomes_non_empty_when_non_null_value_enqueued(String value) 
public class A_non_empty_queue 
public class that_is_not_full 
public void becomes_longer_when_non_null_value_enqueued(String value) 
public void becomes_full_when_enqueued_up_to_capacity() 
public class that_is_full 
public void ignores_further_enqueued_values() 
public void becomes_non_full_when_dequeued() 
public void dequeues_values_in_order_enqueued() 
public void remains_unchanged_when_null_enqueued() 
public class Queue_spec 
public class A_new_queue 
public void is_empty() 
public void preserves_positive_bounding_capacity(int capacity) 
public void cannot_be_created_with_non_positive_bounding_capacity(int capacity) 
public class An_empty_queue 
public void dequeues_an_empty_value() 
public void remains_empty_when_null_enqueued() 
public void becomes_non_empty_when_non_null_value_enqueued(String value) 
public class A_non_empty_queue 
public class that_is_not_full 
public void becomes_longer_when_non_null_value_enqueued(String value) 
public void becomes_full_when_enqueued_up_to_capacity() 
public class that_is_full 
public void ignores_further_enqueued_values() 
public void becomes_non_full_when_dequeued() 
public void dequeues_values_in_order_enqueued() 
public void remains_unchanged_when_null_enqueued() 
public class Queue<T>
{
private Deque<T> items = new LinkedList<>();
private final int capacity;
public Queue(int boundingCapacity)
{
if (boundingCapacity < 1)
throw new IllegalArgumentException();
capacity = boundingCapacity;
}
public int length()
{
return items.size();
}
public int capacity()
{
return capacity;
}
public boolean enqueue(T last)
{
boolean enqueuing = last != null && length() < capacity();
if (enqueuing)
items.addLast(last);
return enqueuing;
}
public Optional<T> dequeue()
{
return Optional.ofNullable(items.pollFirst());
}
}
Structure and Interpretation of Test Cases
Structure and Interpretation of Test Cases

More Related Content

What's hot

Lambdas, Collections Framework, Stream API
Lambdas, Collections Framework, Stream APILambdas, Collections Framework, Stream API
Lambdas, Collections Framework, Stream APIPrabu U
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8Knoldus Inc.
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use casesFabio Biondi
 
ORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSmohdoracle
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Types of exceptions
Types of exceptionsTypes of exceptions
Types of exceptionsmyrajendra
 
SQL BUILT-IN FUNCTION
SQL BUILT-IN FUNCTIONSQL BUILT-IN FUNCTION
SQL BUILT-IN FUNCTIONArun Sial
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutionsAshwin Kumar
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentationVan Huong
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolvedtrxcllnt
 
Web Components and Security
Web Components and SecurityWeb Components and Security
Web Components and SecurityTyler Peterson
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot ApplicationsVMware Tanzu
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
Sync, async and multithreading
Sync, async and multithreadingSync, async and multithreading
Sync, async and multithreadingTuan Chau
 
Oracle Collections
Oracle CollectionsOracle Collections
Oracle CollectionsTrendz Lab
 
Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)Punjab University
 

What's hot (20)

Lambdas, Collections Framework, Stream API
Lambdas, Collections Framework, Stream APILambdas, Collections Framework, Stream API
Lambdas, Collections Framework, Stream API
 
Introduction to Java 8
Introduction to Java 8Introduction to Java 8
Introduction to Java 8
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
 
ORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERSORACLE PL SQL FOR BEGINNERS
ORACLE PL SQL FOR BEGINNERS
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Introduction to OOP(in java) BY Govind Singh
Introduction to OOP(in java)  BY Govind SinghIntroduction to OOP(in java)  BY Govind Singh
Introduction to OOP(in java) BY Govind Singh
 
Java logging
Java loggingJava logging
Java logging
 
Types of exceptions
Types of exceptionsTypes of exceptions
Types of exceptions
 
SQL BUILT-IN FUNCTION
SQL BUILT-IN FUNCTIONSQL BUILT-IN FUNCTION
SQL BUILT-IN FUNCTION
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
 
Java basic
Java basicJava basic
Java basic
 
Java 8 presentation
Java 8 presentationJava 8 presentation
Java 8 presentation
 
RxJS Evolved
RxJS EvolvedRxJS Evolved
RxJS Evolved
 
Web Components and Security
Web Components and SecurityWeb Components and Security
Web Components and Security
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot Applications
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
Sync, async and multithreading
Sync, async and multithreadingSync, async and multithreading
Sync, async and multithreading
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Oracle Collections
Oracle CollectionsOracle Collections
Oracle Collections
 
Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)Presentation slides of Sequence Query Language (SQL)
Presentation slides of Sequence Query Language (SQL)
 

Similar to Structure and Interpretation of Test Cases

Programming with GUTs
Programming with GUTsProgramming with GUTs
Programming with GUTscatherinewall
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkHumberto Marchezi
 
Junit mockito and PowerMock in Java
Junit mockito and  PowerMock in JavaJunit mockito and  PowerMock in Java
Junit mockito and PowerMock in JavaAnkur Maheshwari
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testingEric (Trung Dung) Nguyen
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonbeITconference
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean testsDanylenko Max
 
淺談高效撰寫單元測試
淺談高效撰寫單元測試淺談高效撰寫單元測試
淺談高效撰寫單元測試Zen K.C
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)Steve Upton
 
Dev labs alliance top 20 testng interview questions for sdet
Dev labs alliance top 20 testng interview questions for sdetDev labs alliance top 20 testng interview questions for sdet
Dev labs alliance top 20 testng interview questions for sdetdevlabsalliance
 
05 junit
05 junit05 junit
05 junitmha4
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testingpleeps
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Gianluca Padovani
 
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...acijjournal
 
Hitchhiker's guide to Functional Testing
Hitchhiker's guide to Functional TestingHitchhiker's guide to Functional Testing
Hitchhiker's guide to Functional TestingWiebe Elsinga
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven DevelopmentDhaval Dalal
 

Similar to Structure and Interpretation of Test Cases (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
Programming with GUTs
Programming with GUTsProgramming with GUTs
Programming with GUTs
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing Framework
 
Junit mockito and PowerMock in Java
Junit mockito and  PowerMock in JavaJunit mockito and  PowerMock in Java
Junit mockito and PowerMock in Java
 
The real beginner's guide to android testing
The real beginner's guide to android testingThe real beginner's guide to android testing
The real beginner's guide to android testing
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Test for AI model
Test for AI modelTest for AI model
Test for AI model
 
How to write clean tests
How to write clean testsHow to write clean tests
How to write clean tests
 
淺談高效撰寫單元測試
淺談高效撰寫單元測試淺談高效撰寫單元測試
淺談高效撰寫單元測試
 
Unit testing with JUnit
Unit testing with JUnitUnit testing with JUnit
Unit testing with JUnit
 
DSR Testing (Part 1)
DSR Testing (Part 1)DSR Testing (Part 1)
DSR Testing (Part 1)
 
Dev labs alliance top 20 testng interview questions for sdet
Dev labs alliance top 20 testng interview questions for sdetDev labs alliance top 20 testng interview questions for sdet
Dev labs alliance top 20 testng interview questions for sdet
 
05 junit
05 junit05 junit
05 junit
 
TestNG vs Junit
TestNG vs JunitTestNG vs Junit
TestNG vs Junit
 
Grails unit testing
Grails unit testingGrails unit testing
Grails unit testing
 
Tdd is not about testing (OOP)
Tdd is not about testing (OOP)Tdd is not about testing (OOP)
Tdd is not about testing (OOP)
 
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...
AUTOCODECOVERGEN: PROTOTYPE OF DATA DRIVEN UNIT TEST GENRATION TOOL THAT GUAR...
 
Hitchhiker's guide to Functional Testing
Hitchhiker's guide to Functional TestingHitchhiker's guide to Functional Testing
Hitchhiker's guide to Functional Testing
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 

More from Kevlin Henney

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical ExcellenceKevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical DevelopmentKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that LetterKevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid DeconstructionKevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayKevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to ImmutabilityKevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-InKevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good NameKevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantKevlin Henney
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our WaysKevlin Henney
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersKevlin Henney
 

More from Kevlin Henney (20)

The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many ProgrammersSeven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
 

Recently uploaded

SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdfAndrey Devyatkin
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jNeo4j
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 

Recently uploaded (20)

SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
2024-04-09 - From Complexity to Clarity - AWS Summit AMS.pdf
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4jGraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
GraphSummit Madrid - Product Vision and Roadmap - Luis Salvador Neo4j
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 

Structure and Interpretation of Test Cases