c# itextsharp pdfreader not opened with owner password : Add and remove pages from a pdf application control cloud windows web page .net class The%20Art%20of%20Unit%20Testing%20with%20Examples%20in%20.NET%20(Manning%202009)19-part1050

Building a test API for your application
165
Figure 6.6 A standard test class hierarchy implementation. Most of the tests are in 
the base class, but derived classes can add their own specific tests.
Figure 6.6 shows the visual inheritance chain that we’ve just created.
How do we modify existing code to use this pattern? That’s our next topic.
Refactoring your test class into a test class hierarchy
Most developers don’t start writing their tests with these inheritance 
patterns in mind. Instead, they write the tests normally, as was shown 
in listing 6.5. The steps to convert your tests into a base class are fairly 
easy, particularly if you have IDE refactoring tools available, like the 
ones  found  in  Eclipse,  IntelliJ  IDEA,  or  Visual  Studio  2008  (Jet-
Brains’ ReSharper or Refactor! from DevExpress). 
Here is a list of possible steps for refactoring your test class:
1
Refactor: extract the superclass.
Create a base class (
BaseXXXTests
).
Move the factory methods (like 
GetParser
) into the base class.
Move all the tests to the base class.
2
Refactor: make factory methods abstract, and return interfaces.
3
Refactor: find all the places in the test methods where explicit class 
types are used, and change them to use the interfaces of those types 
instead.
Add and remove pages from a pdf - remove PDF pages in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Provides Users with Mature Document Manipulating Function for Deleting PDF Pages
delete pages on pdf file; delete pages from pdf acrobat reader
Add and remove pages from a pdf - VB.NET PDF Page Delete Library: remove PDF pages in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Visual Basic Sample Codes to Delete PDF Document Page in .NET
delete pdf pages online; delete page from pdf file online
166
CHAPTER 6    Test hierarchies and organization
4
In the  derived  class, implement the abstract  factory methods and 
return the explicit types.
You can also use .NET generics to create the inheritance patterns.
A variation using .NET generics to implement test hierarchy
You can use generics as part of the base test class. This way, you don’t 
even need to override any methods in derived classes; just declare the 
type you’re testing against. Listing 6.8 shows both the generic version 
of the test base class and a class derived from it.
Listing 6.8  Implementing test case inheritance with .NET generics
public abstract class StringParserTests<T>
where T:IStringParser         
{
protected T GetParser(string input) 
{
return (T) Activator.CreateInstance(typeof (T), input);
}
[Test]
public void GetStringVersionFromHeader_SingleDigit_Found()
{
string input = "header; \n";
T parser = GetParser(input);  
bool result = parser.HasCorrectHeader();
Assert.IsFalse(result);
}
//more tests
//...
}
// this is the derived test class:
[TestFixture]
public class StandardStringParserGenericTests
:StringParserTests<StandardStringParser>
{
}
Defines generic  
constraint  
on parameter
?
Returns generic type
w
Gets generic type  
variable instead  
of an interface
e
Inherits  
from generic  
base class
VB.NET PDF Password Library: add, remove, edit PDF file password
manipulations. Open password protected PDF. Add password to PDF. Change PDF original password. Remove password from PDF. Set PDF security level. VB
delete page from pdf acrobat; cut pages from pdf preview
C# PDF Password Library: add, remove, edit PDF file password in C#
String outputFilePath = Program.RootPath + "\\" Output.pdf"; // Remove the password. doc.Save(outputFilePath); C# Sample Code: Add Password to Plain PDF
delete pages out of a pdf; cut pages from pdf reader
Building a test API for your application
167
There are several things that change in the generic implementation of 
the hierarchy:
The 
GetParser
factory method w no longer needs to be overridden. 
Create  the  object  using 
Activator.CreateInstance
(which  allows 
creating  objects  without  knowing  their  type)  and  send  the  input 
string arguments to the constructor.
The  tests  themselves  don’t  use  the 
IStringParser
interface,  but 
instead use the T generic type e.
The generic class declaration contains the 
where
clause that specifies 
that the T type of the class must implement the 
IStringParser
inter-
face ?.
Overall, I don’t find more benefit in using generic base classes. Any 
performance gain that would result is insignificant to these tests, but I 
leave it to you to see what makes sense for your projects. It’s more a 
matter of taste than anything else.
Let’s move on to something completely different: infrastructure API in 
your test projects.
6.5.2 Creating test utility classes and methods 
As you write your tests, you’ll also create many simple utility methods 
that  may  or  may  not  end  up  inside  your  test  classes.  These  utility 
classes become a big part of your test API, and they may turn out to be 
a simple object model you could use as you develop your tests.
You might end up with the following types of utility methods:
Factory methods for objects that are complex to create or that rou-
tinely get created by your tests.
System  initialization methods  (such  as  methods for setting  up the 
system state before testing, or changing logging facilities to use stub 
loggers).
Object  configuration  methods  (for  example,  methods  that  set  the 
internal state of an object, such as setting a customer to be invalid for 
a transaction).
C# PDF Digital Signature Library: add, remove, update PDF digital
Image: Insert Image to PDF. Image: Remove Image from Redact Text Content. Redact Images. Redact Pages. Annotation & Highlight Text. Add Text. Add Text Box. Drawing
delete page on pdf document; delete page on pdf file
C# PDF remove image library: remove, delete images from PDF in C#.
Image: Insert Image to PDF. Image: Remove Image from Redact Text Content. Redact Images. Redact Pages. Annotation & Highlight Text. Add Text. Add Text Box. Drawing
delete pages from pdf reader; delete pages of pdf reader
168
CHAPTER 6    Test hierarchies and organization
Methods that set up or read from external resources such as data-
bases, configuration files, and test input files (for example, a method 
that loads a text file with all the permutations you’d like to use when 
sending in inputs for a specific method, and the expected results). 
This is more commonly used in integration or system testing.
Special  assert  utility  methods,  which  may  assert  something  that’s 
complex  or  that’s  repeatedly  tested  inside  the  system’s  state.  (If 
something was written to the system log, the method might assert 
that X, Y, and Z are 
true
, but not G.)
You may end up refactoring your utility methods into these types of 
utility classes:
Special assert utility classes that contain all the custom assert methods
Special factory classes that hold the factory methods
Special configuration classes or database configuration classes that 
hold integration style actions
Having those utility methods around doesn’t guarantee anyone will use 
them. I’ve been to plenty of projects where developers kept reinventing 
the wheel, recreating utility methods they didn’t know already existed. 
That’s why making your API known is an important next step.
6.5.3 Making your API known to developers
It’s imperative that the people who write tests know about the various 
APIs that have been developed while writing the application and  its 
tests. There are several ways to make sure your APIs are used:
Have teams of  two  people  write  tests  together  (at  least once in  a 
while), where one of the people is familiar with the  existing APIs
and can teach the other person, as they write new tests, about the 
existing benefits and code that could be used.
Have a short document (no more than a couple of pages) or a cheat 
sheet that details the types of APIs out there and where to find them. 
You  can create  short  documents  for  specific  parts  of your  testing 
framework (APIs specific to the data layer, for example) or a global 
one for the whole application. If it’s not short, no one will maintain it. 
C# PDF bookmark Library: add, remove, update PDF bookmarks in C#.
Help to add or insert bookmark and outline into PDF file in .NET framework. Ability to remove and delete bookmark and outline from PDF document.
delete pages out of a pdf file; cut pages from pdf online
C# PDF metadata Library: add, remove, update PDF metadata in C#.
Add metadata to PDF document in C# .NET framework program. Remove and delete metadata from PDF file. Also a PDF metadata extraction control.
delete pages from pdf acrobat; delete blank page in pdf online
Summary
169
One possible way to make sure it’s up to date is by automating the 
generation process:
Have  a  known  set  of  prefixes  or  postfixes on  the  API helpers’ 
names (helperXX for example).
Have a special tool that parses out the names and their locations 
and generates a document that lists them and where to find them, 
or have some simple directives that the special tool can parse from 
comments you put on them.
Automate  the  generation of  this  document  as  part  of  the  auto-
mated build process.
Discuss changes to the APIs during team meetings—one or two sen-
tences outlining the main changes and where to look for the signifi-
cant parts. That way the team knows that this is important and it’s 
always on people’s minds.
Go over this document with new employees during their orientation.
Perform test reviews (as opposed to code reviews) that make sure 
tests are up to standards of readability, maintainability, and correct-
ness, and ensure that the right APIs are used when needed.
Following one or more of these recommendations can help keep your 
team productive  and will create a shared  language the team can use 
when writing their tests.
Let’s look back and see what we can draw out from the chapter we’ve 
been through.
Whatever testing you do—however you do it—automate it, and use 
an automated build procedure to run it as  many times as possible 
during day or night.
Separate the integration tests from the unit tests (the slow tests from 
the fast ones) so that your team can have a safe green zone where all 
the tests must pass.
Map out tests by project and by type (unit versus integration tests, 
slow versus fast tests), and separate them into different directories, 
6.6 Summary
VB.NET PDF remove image library: remove, delete images from PDF in
Image: Insert Image to PDF. Image: Remove Image from Redact Text Content. Redact Images. Redact Pages. Annotation & Highlight Text. Add Text. Add Text Box. Drawing
delete pages pdf file; cut pages from pdf file
VB.NET PDF metadata library: add, remove, update PDF metadata in
Add permanent metadata to PDF document in VB .NET framework program. Remove and delete metadata content from PDF file in Visual Basic .NET application.
delete pages from a pdf online; add and remove pages from a pdf
170
CHAPTER 6    Test hierarchies and organization
folders, or namespaces (or all of the above). I usually use all three 
types of separation.
Use a test class hierarchy to apply the same set of tests to multiple 
related types under test in a hierarchy, or to types that share a com-
mon interface or base class.
Use helper classes and utility classes instead of hierarchies if the test 
class  hierarchy  makes  tests  less  readable,  especially  if  there’s  a 
shared setup method in the base class. Different people have differ-
ent opinions on when to use which, but readability is usually the key 
reason for not using hierarchies.
Make your API known to your team. If you don’t, you’ll lose time 
and  money  as  team  members  unknowingly  reinvent  many  of  the 
APIs over and over again.
The next three chapters will deal with practices you can use to make 
your tests more maintainable, readable, and correct (in the sense that 
they test the right things).
171
The pillars of good tests
This chapter covers
•Writing trustworthy tests
•Writing maintainable tests
•Writing readable tests
•Exploring naming conventions for unit tests
o matter  how you organize your tests,  or how many you have, they’re 
worth very  little  if you can’t trust them, maintain them,  or read  them. 
The tests that you write should have three properties that together make 
them 
good
:
Trustworthiness—
Developers will 
want
to run trustworthy tests, and they’ll 
accept  the test results with  confidence. Trustworthy tests don’t have 
bugs, and they test the right things. 
Maintainability—
Nonmaintainable tests are nightmares because they can 
ruin project schedules, or you risk losing the tests when the project is 
put on a more aggressive schedule. Developers will simply stop main-
taining and fixing tests that take too long to change. 
Readability—
This means not just being able to read a test but also figur-
ing out the problem if the test seems to be wrong. Without readability, 
the  other  two  pillars  fall  pretty  quickly.  Maintaining  tests  becomes 
harder, and you can’t trust them anymore.
N
172
CHAPTER 7    The pillars of good tests
This chapter presents a series of practices related to each of these three 
pillars that you can use when doing test reviews. Together, the three 
pillars ensure your time is well used. Drop one of them, and you run 
the risk of wasting everyone’s time.
There are several indications that a test is trustworthy. If it passes, you 
don’t say, “I’ll step through the code in the debugger to make sure.” 
You trust that it passes and that the code it tests works for that specific 
scenario. If the test fails, you don’t tell yourself, “Oh, it’s supposed to 
fail,” or “That doesn’t mean the code isn’t working.” You believe that 
there’s a problem in your code and not in your test. In short, a trust-
worthy test is one that makes you feel you know what’s going on and 
that you can do something about it. 
In this chapter, I’ll introduce guidelines and techniques to help you do 
the following:
Decide when to remove or change tests
Avoid test logic
Test only one thing
Make tests easy to run
Assure code coverage
I’ve found that tests that follow these guidelines tend to be tests that I 
can trust more than others, and that I feel confident will continue to 
find errors in my code. 
7.1.1 Deciding when to remove or change tests
Once  you  have  tests  in  place,  you  should  generally  not  change  or 
remove them. They are there as your safety net, to let you know if any-
thing breaks when you change your code. That said, there are times 
you might feel compelled to change or remove existing tests. To under-
stand when this might cause a problem and when it’s reasonable to do 
so, let’s look at the reasons for each. 
7.1 Writing trustworthy tests
Writing trustworthy tests
173
The main reason for removing a test is when it fails. A test can “sud-
denly” fail for several reasons:
Production bugs
—There’s a bug in the production code under test.
Test bugs
—There’s a bug in the test.
Semantics  or  API  changes
—The  semantics  of  the  code  under  test 
changed, but not the functionality.
Conflicting or invalid tests
—The production code was changed to reflect 
a conflicting requirement.
There are also reasons for changing or removing tests when nothing is 
wrong with the tests or code: 
To rename or refactor the test
To eliminate duplicate tests
Let’s see how you might deal with each of these cases.
Production bugs
A production bug occurs when you change the production code and an 
existing test breaks. If indeed this is a bug in the code under test, your 
test is fine, and you shouldn’t need to touch the test. This is the best 
and most desired outcome of having tests.
Because the occurrence of production bugs is one of the main reasons 
we have unit tests in the first place, the only thing left to do is to fix the 
bug in the production code. Don’t touch the test.
Test bugs
If there’s a bug in the test, you need to change the test. Bugs in tests are 
notoriously hard to detect in the first place, because the test is assumed 
to be correct. I’ve detected several stages developers go through when 
a test bug is encountered:
1
Denial
—The
developer will keep looking for a problem in the code 
itself,  changing  it,  causing all  the other  tests to  start  failing.  The 
developer introduces 
new
bugs into production code while hunting 
for the bug that’s actually in the test.
2
Amusement
—The
developer  will  call  another  developer,  if  possible, 
and they will hunt for the non-existent bug together.
174
CHAPTER 7    The pillars of good tests
3
Debuggerment
—The
developer will patiently debug the test and dis-
cover that  there’s  a  problem  in  the  test.  This can  take  anywhere 
from an hour to a couple of days.
4
Acceptance and slappage
—The
developer will eventually realize where 
the bug is, and will slap herself on the forehead.
When you finally find and start fixing the bug, it’s important to make 
sure that the bug gets fixed, and that the test doesn’t magically pass by 
testing the wrong thing. You need to do the following:
1
Fix the bug in your test.
2
Make sure the test fails when it should.
3
Make sure the test passes when it should.
The first step, fixing the test, is  quite straightforward. The next two 
steps make sure you’re still testing the correct thing, and that your test 
can still be trusted. 
Once you have fixed your test, go to the production code under test 
and change it so that it manifests the bug that the test is supposed to 
catch. Then run the test. If the test fails, that means it’s half working. 
The other half will be completed in step 3. If the test doesn’t fail, you’re 
most likely testing the wrong thing. (I’ve seen developers accidentally 
delete the asserts from their tests when fixing bugs in tests. You’d be 
surprised how often that happens and how effective step 2 is at catch-
ing these cases.)
Once you see the test fail, change your production code so that the bug 
no longer exists. The test should now pass. If it doesn’t, you either still 
have a bug in your test, or you’re testing the wrong thing. You want to 
see the test fail and then pass again after you fix it so that you can be 
sure that it fails and passes when it should.
Semantics or API changes
A test can fail when the production code under test changes so that an 
object being tested now needs to be 
used
differently, even though it may 
still have the same end functionality.
Documents you may be interested
Documents you may be interested