<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7763195273365582447</id><updated>2024-08-30T06:53:28.806-04:00</updated><category term="Git"/><category term="Java"/><category term="Perl"/><category term="software design"/><category term="Apache"/><category term="Buffers"/><category term="Efficiency"/><category term="GET"/><category term="GitHub"/><category term="JDBC"/><category term="LAMP"/><category term="Large documents"/><category term="MySQL"/><category term="Regex"/><category term="SQL"/><category term="Split"/><category term="Streams"/><category term="Tomcat"/><category term="UX"/><category term="Usability engineering"/><category term="bash"/><category term="black box test"/><category term="command"/><category term="commands"/><category term="integration test"/><category term="operators"/><category term="scraping"/><category term="software architecture"/><category term="software testing"/><category term="system test"/><category term="tips"/><category term="unit test"/><category term="user interaction experience"/><category term="user interface design"/><category term="version control"/><category term="web design"/><category term="white box test"/><title type='text'>Universe of Discourse: Software Engineering</title><subtitle type='html'>PLAN / CODE / TEST / REPEAT / DEPLOY</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>11</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4344990209766196369</id><published>2011-09-27T01:03:00.000-04:00</published><updated>2011-09-27T01:10:33.507-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Buffers"/><category scheme="http://www.blogger.com/atom/ns#" term="Efficiency"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Large documents"/><category scheme="http://www.blogger.com/atom/ns#" term="Regex"/><category scheme="http://www.blogger.com/atom/ns#" term="Split"/><category scheme="http://www.blogger.com/atom/ns#" term="Streams"/><title type='text'>Splitting text on white-space efficiently in Java</title><content type='html'>&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;Small data, small problem. Big data, ...&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
Splitting text on white-space in most programming languages is normally a trivial matter. This task becomes a lot more difficult though when you try to complete it over a very large document collection.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The easiest way to split a document on white-space is to use the split method, which is implemented by default in most languages on String objects. Although the split method produces the end result we are looking for, it is not the most efficient way to manipulate large sets of data.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Strings and Streams&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
In Java, it can be advantageous to use streams over Strings since streams allow the programmer greater flexibility in the specifying the I/O buffer size. By specifying an optimal buffer size for the input stream, the programmer can reduce the the number of disk reads that need to be performed in order to load the contents of a file into memory. Less I/O means more performance.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Use Buffered I/O&lt;/span&gt; (for text documents, in this case)&lt;/div&gt;
&lt;div&gt;
Since the purpose of buffered I/O is to reduce the number of disk reads necessary to load a file, you can imagine that knowing the size of the file prior to loading it is important. After the size of the file we want to load is known, we create a character array store the contents of the file one character at a time. (Note that the character encoding of the document you are reading impacts the number of bits or bytes used to represent a character.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;The Split Function&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
At this point we have our document stored within a char array and need to start splitting it into individual words or tokens efficiently. Since we are dealing with a char array, we no longer have the String method &quot;split&quot; available. The strategy here is to step through the entire char array (document) one time and pick out all of the words to be stored (say in a dictionary). In order to achieve this task the trick is to keep track of when a word begins and ends in the stream. This can be done by using a simple Boolean flag within the loop which iterates through the character array.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
First determine whether or not the first character is white-space or not. This is important since we need to know whether we are looking for the beginning of a word first or whether we&#39;re looking for the end. Assuming the document starts with a word instead of white space, we take note of the fact that we are currently iterating over a word. Once we realize that the word has ended (a space has been encountered) we mark the end of the word, add it to the dictionary and set our Boolean flag to record that we are no longer on a word. At this point, as we iterate through the document further, should any additional white-space be encountered, it will be ignored. The next time something interesting happens in the code is when we reach a non white-space character, at which point we reset our Boolean flag to reflect that we are at a word boundary again and take note of where it starts. Then we move on looking for the next instance of white-space to find the ending boundary of the latest term discovered.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I know that explaining an algorithm can often sound convoluted and so I have attached a small code sample that demonstrates the technique of using streams and character arrays to efficiently process large document sets.&lt;/div&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.BufferedReader;
import java.util.ArrayList;

public class Driver {

	public static void main(String[] args) {
		// Set the location of the corpus
		File corpus = new File(&quot;/path/to/document/collection&quot;);
		// Iterate through the files and perform the necessary actions
		File[] files = corpus.listFiles();
		for(File f : files) {
			try {
				
				// Get the size of the file, create a byte stream and a character array to store the input
				int file_size = (int) f.length();
				Reader input = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
				char[] data = new char[file_size];
				
				// Create an array list to store the tokens
				ArrayList&lt;string&gt; tokens = new ArrayList&lt;string&gt;();

				// Read the file
				while (input.read(data, 0, file_size) != -1) {

				  // Determine whether we are starting with whitespace
				  boolean at_token = Character.isWhitespace(data[0]) ? false: true;
				  
				  // Keep track of the bounds of tokens
				  int left = 0, right = 0;
				  
				  // Iterate through the data stream
                  for(int i = 0; i &amp;lt; data.length; i++) {
                	// Found the beginning of a token
                	if (!Character.isWhitespace(data[i]) &amp;amp;&amp;amp; at_token == false) {
                      at_token = true;
                      left = i;
                    }
                	// Found the end of a token
                	if (Character.isWhitespace(data[i]) &amp;amp;&amp;amp; at_token == true) {	
                      at_token = false;
                      right = i;
                      StringBuilder token = new StringBuilder(right-left);
  					  token.append(data, left, right-left);
  					  tokens.add(token.toString());
                    }
                  }
				}
				int ctr = 0;
				for (String s : tokens) {
					System.out.println(&quot;Token #&quot;+ctr+&quot;\t&quot;+s);
					ctr++;
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4344990209766196369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/09/splitting-text-on-white-space.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4344990209766196369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4344990209766196369'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/09/splitting-text-on-white-space.html' title='Splitting text on white-space efficiently in Java'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4672510339980736332</id><published>2011-06-13T14:42:00.000-04:00</published><updated>2011-06-13T14:42:17.892-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="GitHub"/><title type='text'>Starting a new Repository on GitHub</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: helvetica, arial, freesans, clean, sans-serif; font-size: 13px; line-height: 18px;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h2 style=&quot;line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;These are the instructions that GitHub provides you with in order to create a new repository.&lt;/span&gt;&lt;/h2&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;Note: replace the name John Doe with your actual GitHub user name. Also replace the email and don&#39;t forget to name your app.&lt;/span&gt;&lt;/div&gt;&lt;h2 style=&quot;line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/h2&gt;&lt;h2 style=&quot;line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;Global setup:&lt;/h2&gt;&lt;pre style=&quot;font-size: 13px; font: normal normal normal 12px/normal &#39;Bitstream Vera Sans Mono&#39;, Courier, monospace; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;Download and install &lt;a href=&quot;http://git-scm.com/download&quot; style=&quot;color: #4183c4; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: none; outline-width: initial; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none;&quot; target=&quot;_blank&quot;&gt;Git&lt;/a&gt;
  git config --global user.name &quot;John Doe&quot;
  git config --global user.email john.doe@gmail.com
        &lt;/pre&gt;&lt;h2 style=&quot;line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;Next steps:&lt;/h2&gt;&lt;pre style=&quot;font-size: 13px; font: normal normal normal 12px/normal &#39;Bitstream Vera Sans Mono&#39;, Courier, monospace; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;mkdir Name-Your-App
  cd Name-Your-App
  git init
  touch README
  git add README
  git commit -m &#39;first commit&#39;
  git remote add origin git@github.com:JohnDoe/Name-Your-App.git
  git push -u origin master
      &lt;/pre&gt;&lt;h2 style=&quot;line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;Existing Git Repo?&lt;/h2&gt;&lt;pre style=&quot;font-size: 13px; font: normal normal normal 12px/normal &#39;Bitstream Vera Sans Mono&#39;, Courier, monospace; line-height: 1.4em; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot;&gt;cd existing_git_repo
  git remote add origin git@github.com:JohnDoe/Twitter-Apps.git
  git push -u origin master&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4672510339980736332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/06/starting-new-repository-on-github.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4672510339980736332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4672510339980736332'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/06/starting-new-repository-on-github.html' title='Starting a new Repository on GitHub'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-7494492150351355548</id><published>2011-03-17T00:38:00.000-04:00</published><updated>2011-03-17T00:38:32.218-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="commands"/><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="tips"/><category scheme="http://www.blogger.com/atom/ns#" term="version control"/><title type='text'>Git Handbook</title><content type='html'>Git is version control software that allows coders to tinker with their code without compromising the project&#39;s code. Here are the basics you&#39;ll need to git going with Git.&lt;br /&gt;
&lt;hr /&gt;Git Configuration&lt;br /&gt;
Set your email that will appear in commit messages.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git config user.email youremail@example.com&lt;/pre&gt;&lt;br /&gt;
Set your name that will appear in commit messages.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git config user.name &#39;FirstName LastName&#39;&lt;/pre&gt;&lt;br /&gt;
Recommended: Tells git-branch and git-checkout to setup new branches so that git-pull will appropriately merge from that remote branch. Without this, you will have to add --track to your branch command or manually merge remote tracking branches with &quot;fetch&quot; and then &quot;merge&quot;.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git config branch.autosetupmerge true&lt;/pre&gt;&lt;br /&gt;
You can add &quot;--global&quot; after &quot;git config&quot; to any of the above commands to make it&lt;br /&gt;
apply to all git repos (note this will edit the ~/.gitconfig).&lt;br /&gt;
&lt;br /&gt;
Clone the specified repository by &amp;lt;repo&amp;gt; this is similar to &quot;checkout&quot; in some other version control systems such as Subversion and CVS&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git clone &amp;lt;repo&amp;gt;&lt;/pre&gt;&lt;hr /&gt;Gathering information from Git&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git diff&lt;/pre&gt;&lt;br /&gt;
Show files added to the index, files with changes, and untracked files&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git status&lt;/pre&gt;&lt;br /&gt;
Show recent commits, most recent on top&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git log&lt;/pre&gt;&lt;br /&gt;
Show the changeset (diff) of a commit specified by &amp;lt;rev&amp;gt;, which can be any SHA1 commit ID, branch name, or tag&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git show &amp;lt;rev&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Show who authored each line in &amp;lt;file&amp;gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git blame &amp;lt;file&amp;gt; &lt;/pre&gt;&lt;br /&gt;
Show who authored each line in &amp;lt;file&amp;gt; as of &amp;lt;rev&amp;gt; (allows blame to go back in time)&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;git blame &amp;lt;file&amp;gt; &amp;lt;rev&amp;gt;&lt;/pre&gt;&lt;hr /&gt;As usual, &amp;nbsp;you can expect more to come soon.</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/7494492150351355548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/03/git-handbook.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/7494492150351355548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/7494492150351355548'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/03/git-handbook.html' title='Git Handbook'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4227947461179976381</id><published>2011-02-26T16:06:00.018-05:00</published><updated>2011-04-29T00:31:14.121-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="software architecture"/><category scheme="http://www.blogger.com/atom/ns#" term="software design"/><title type='text'>Software Architecture</title><content type='html'>&lt;b&gt;Definition of Software Architecture &lt;/b&gt;(IEEE 1471-2000)&lt;br /&gt;
The fundamental organization of a system [as] embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Where does software architecture fit in?&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU1ON9x7056qSPQ57ZC8esWJt1-A31jeGGb-Z536beXnPsqnuXSmFppoEH6h3wZCw2i1yubIFj-jLkQ2iAxewNvDsDlb3HK-ELbN15Ixdy62IuyMUnqXpMjqucDRoDmN6xSlNUmKF5Vzqb/s1600/RationalUnifiedProcess.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;216&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU1ON9x7056qSPQ57ZC8esWJt1-A31jeGGb-Z536beXnPsqnuXSmFppoEH6h3wZCw2i1yubIFj-jLkQ2iAxewNvDsDlb3HK-ELbN15Ixdy62IuyMUnqXpMjqucDRoDmN6xSlNUmKF5Vzqb/s320/RationalUnifiedProcess.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Rational Unified Process (RUP)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;Software architecture becomes increasingly important as the size of the code base and project increases. This doesn&#39;t mean that you should neglect the architecture of a project until it becomes too difficult to manage. In the context of the &lt;a href=&quot;http://en.wikipedia.org/wiki/IBM_Rational_Unified_Process&quot;&gt;Rational Unified Process (RUP)&lt;/a&gt;, the architecture would be considered between the requirements and implementation phases, effectively during the analysis and design stage. In terms of the design, the architecture can be viewed as the top-level design which is then further elaborated upon in the detailed design (Class diagrams, System Sequence diagrams, etc...). Naturally, since the architecture can be viewed as the top-level design, and fits into the RUP just after the requirements phase has commenced, a highly dependent relationship exists between the two phases. As we&#39;ve seen above, architecture can be viewed as a form of design, but it should be noted that not all design activities are architectural activities. The levels of &amp;nbsp;design, from the top-most layer are, architectural design, detailed design and lastly the implementation (executable designs).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Benefits of an Architectural Design&lt;/b&gt;&lt;br /&gt;
- Reduced rates of failure&lt;br /&gt;
- Qualify rationale for architectural decisions&lt;br /&gt;
- Outline and mitigate risks&lt;br /&gt;
- Schedule and cost projects more effectively&lt;br /&gt;
- Useful for learning about the system&lt;br /&gt;
- Re-use of architectural styles&lt;br /&gt;
- Increases maintainability&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Requirements Versus Design&lt;/b&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Requirements Artifacts&lt;/th&gt;&lt;th&gt;Design Artifacts&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;Domain Model&lt;/td&gt;    &lt;td&gt;Software Architecture Document&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;Use-Cases&lt;/td&gt;    &lt;td&gt;Design Model&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;Non-Functional Requirements&lt;/td&gt;    &lt;td&gt;User-Interface Design&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;How To Start Your Design&lt;/b&gt;&lt;br /&gt;
A natural way to begin the design is to build on some of the work that you&#39;ve already put in. The domain model is an excellent place to create the first approximation of the design &amp;nbsp;as it guides the designers into crafting a solution with a minimal &lt;a href=&quot;http://books.google.ca/books?id=r8i-4En_aa4C&amp;amp;pg=PA146&amp;amp;lpg=PA146&amp;amp;dq=larman+representational+gap&amp;amp;source=bl&amp;amp;ots=mU9KRZAiM-&amp;amp;sig=ycZ3UNRfk8-xX5dbuKbq3F2XrU4&amp;amp;hl=en&amp;amp;ei=dk9pTZHzNYO78gb2kfHDCw&amp;amp;sa=X&amp;amp;oi=book_result&amp;amp;ct=result&amp;amp;resnum=1&amp;amp;ved=0CBwQ6AEwAA#v=onepage&amp;amp;q&amp;amp;f=false&quot;&gt;representational gap&lt;/a&gt;. Whenever tasked with creating a design for a software project always consider whether this same type of application has been created in the past. If so, then analyze how the current solutions are implemented and make use of whatever code or structure is available. Quite often an architectural style will have already been applied to the problem which you may likely want to re-use.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;th colspan=&quot;5&quot;&gt;Common Architectural Styles&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;th&gt;Data-Flow&lt;/th&gt; &lt;th&gt;Data-Centered&lt;/th&gt; &lt;th&gt;Virtual Machine&lt;/th&gt; &lt;th&gt;Call and Return&lt;/th&gt; &lt;th&gt;Independent Components&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;Pipes and Filters&lt;/td&gt;   &lt;td&gt;Repository&lt;/td&gt;   &lt;td&gt;Interpreter&lt;/td&gt;   &lt;td&gt;Main Program and Subroutine&lt;/td&gt;   &lt;td&gt;Communicating Processes&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;Batch Sequential&lt;/td&gt;   &lt;td&gt;Blackboard&lt;/td&gt;   &lt;td&gt;Rule-Based System&lt;/td&gt;   &lt;td&gt;Object-Oriented (&amp;amp; Data Abstraction)&lt;/td&gt;   &lt;td&gt;Client/Server&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;Layered&lt;/td&gt;   &lt;td&gt;Event Systems&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;Implicit Invocation&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;&lt;/td&gt;   &lt;td&gt;Explicit Invocation&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conceptual Integrity&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959?ie=UTF8&amp;amp;tag=widgetsamazon-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;The Mythical Man-Month: Essays on Software Engineering, Anniversary Edition (2nd Edition)&quot; src=&quot;http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0201835959&amp;amp;tag=widgetsamazon-20&quot; /&gt;&lt;/a&gt;&quot;I will contend that Conceptual Integrity is the most important consideration in system design. It is better to have a system omit certain anomalous features and improvements, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.&quot;&lt;br /&gt;
&lt;br /&gt;
- The Mythical Man-Month, by Fred Brooks, 1975&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=widgetsamazon-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0201835959&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Enterprise Applications&lt;/b&gt;&lt;br /&gt;
Generally, enterprise applications form a class of software solutions that deal with large volumes of complex data that is persistent and concurrently accessed by many users and or applications. The software does not usually have strong hardware/software integration requirements. A common approach to constructing enterprise applications is to use the layered or client-server architecture.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Enterprise Application Architectural Styles&lt;/b&gt;&lt;br /&gt;
As we&#39;ve just seen, two very common architectures are often employed in the construction of enterprise applications. We&#39;ll now take a closer look at both styles.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Layered Architecture&lt;/u&gt;&lt;br /&gt;
At the most basic level, the layered approach typically consists of at least three layers: presentation, &amp;nbsp;domain and data source. As far as functionality is concerned in the this architecture, lower level layers service requests from higher ones, thus providing functionality upwards from the bottom. Dependencies however move in the opposite direction from higher level layers to lower ones. One variation of the classic layered style exists, the pure layered style, where the dependencies are further restricted by allowing higher level layers to depend solely on services from components within the same layer or the layer immediately below.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;Presentation&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;------------------------------&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;Domain&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;------------------------------&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;Data Source&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;u&gt;Client-Server Architecture&lt;/u&gt;&lt;br /&gt;
Client server applications, such as a web browser will usually utilize the Internet for communications. We&#39;ll provide a few quick definitions of what exactly we mean when we say the Internet versus the web. The Internet is the hardware infrastructure in which the web operates. The web is just software along with a set of associated protocols. As an example, Hyper-Text Transport Protocol (HTTP) is a stateless and fairly simple request-response protocol that is used extensively on the web. Now that the &lt;a href=&quot;http://en.wikipedia.org/wiki/Lingua_franca&quot;&gt;Lingua Franca&lt;/a&gt; has been defined we can better understand the interaction between the clients and servers. A client is responsible for sending HTTP requests to severs, while servers have the task of sending HTTP responses. A web server is a piece of software which implements the web protocols (i.e. HTTP). The clients (more software) make requests using the web protocol to the web servers and receive responses. Web servers can only serve static content, thus helper applications are needed in order for the server to serve dynamic content. An example of one such helper is a Java Servlet. The typical environment in which Java servlets reside is Tomcat, a servlet container. In the weakest possible terms the role of Tomcat is to facilitate the interaction between the web sever and the servlets. &lt;a href=&quot;http://tomcat.apache.org/&quot;&gt;Tomcat&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;th&gt;HTTP Methods&lt;/th&gt; &lt;th&gt;Description&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;GET&lt;/td&gt; &lt;td&gt;get a resource a given URL&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;POST&lt;/td&gt; &lt;td&gt;basically a GET with extra parameters&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;HEAD&lt;/td&gt; &lt;td&gt;GET the header part of the response only&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;TRACE&lt;/td&gt; &lt;td&gt;loopback request message&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;PUT&lt;/td&gt; &lt;td&gt;put info at given URL&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;DELETE&lt;/td&gt; &lt;td&gt;delete the given URL&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;OPTIONS&lt;/td&gt; &lt;td&gt;list the HTTP methods the URL can respond to&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;CONNECT&lt;/td&gt; &lt;td&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;&quot;&gt;This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;&quot;&gt;&lt;a href=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec17.html#bib44&quot; rel=&quot;bibref&quot;&gt;[44]&lt;/a&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;&quot;&gt;).&lt;/span&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKeT8xN7UnYKr6ppHtMwzMrdaDD1UsLOTI1BVml3JDpxIpQK2hUorBz8HKUDeIVBYBMiQqfin7ZdY4zPj2TGluW9Csh5NbU-pN7QgKOLShzEgm9CiBjJNhBP8CkJXoNPcE4XOp2VT1UZmk/s1600/anatomy+of+an+http+request.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;168&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKeT8xN7UnYKr6ppHtMwzMrdaDD1UsLOTI1BVml3JDpxIpQK2hUorBz8HKUDeIVBYBMiQqfin7ZdY4zPj2TGluW9Csh5NbU-pN7QgKOLShzEgm9CiBjJNhBP8CkJXoNPcE4XOp2VT1UZmk/s320/anatomy+of+an+http+request.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The anatomy of an HTTP request, picture by Dr. Chalin&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkXoSXBcFXNYprJFBZUmnykXYpT28uEDF4YT-FV2dWeuiL0DayExxjyY-od2w_Z2NOdAJtPnur59hgZN0ydowDapsG8rfIok2ppCqWGDCa6Wj-pj6HA_6bwopam-xGj4_XhN_3YzYz87CA/s1600/anatomy+of+an+http+response.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;224&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkXoSXBcFXNYprJFBZUmnykXYpT28uEDF4YT-FV2dWeuiL0DayExxjyY-od2w_Z2NOdAJtPnur59hgZN0ydowDapsG8rfIok2ppCqWGDCa6Wj-pj6HA_6bwopam-xGj4_XhN_3YzYz87CA/s320/anatomy+of+an+http+response.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;The anatomy of an HTTP response, Dr. Chalin&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;Pipes and Filters&lt;/b&gt;&lt;br /&gt;
The metaphor of pipes and filters can be directly applied as a software architectural style. A pipe carries a fluid through it until it reaches a filter. The filter then outputs it&#39;s modified fluid back into another pipe. In using this metaphor &amp;nbsp;as a basis for the software implementation say that a pipe should carry data between filters and a filter should accept data and output it to a pipe. The advantages of using this data flow style is that it assumes concurrent processing since output from a pipe can be continuously consumed by a filter while simultaneously outputting it&#39;s content to another pipe and ultimately filter. Each filters is independent all other filters, thus each filter maintains it&#39;s own state. Filters are thought of black boxes and are only responsible for accepting input in a specific format and outputting data in a specific format, thus filters can be swapped easily. No complex interactions exists in pipes, simple data transfers are the only responsibility of pipes. Some weaknesses of this style are that it&#39;s use can lead to batch sequential programming, it is also not well suited for interactive applications. As mentioned a data format must be defined for the input and output of the filters, thus additionally complexity is added to the filters for the encoding of decoding of outputs.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Variations of Pipes and Filters&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;Pipeline:&lt;/u&gt;&amp;nbsp;A linear sequence of filters.&lt;br /&gt;
&lt;u&gt;Batch Sequential System:&lt;/u&gt;&amp;nbsp;A pipeline in which each filter runs to completion before the next begins.&lt;br /&gt;
&lt;u&gt;Bounded Pipes:&lt;/u&gt;&amp;nbsp;Restriction on the amount of data that can be temporarily in a pipe.&lt;br /&gt;
&lt;u&gt;Types Pipes:&lt;/u&gt;&amp;nbsp;The data passed between two filters is restricted to a well-defined type.&lt;br /&gt;
&lt;u&gt;UI Pipes:&lt;/u&gt;&amp;nbsp;Each filter is associated with a user-interface to allow the user to set parameters of operation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Event-Based Architecture&lt;/b&gt;&lt;br /&gt;
Event-based programming is the chief architecture used in the development of graphical user interfaces. Someone clicks a button for instance and an event is fired notifying someone else that the button has been pressed and action must now be taken. It is also well suited for multi-core systems since events can be processed in a number of locations. UML2 has even made provisions for it within it&#39;s specification.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Components and Connectors&lt;/b&gt;&lt;br /&gt;
A component is an active or passive object, capsule or module. A connector is a callback, channel or binding. Notable component types are publishers and subscribers. A component does not explicitly invoke another component, instead an event is generated (message is passed). In order for a component to become aware of events stemming from another component it must subscribe or register with component. This relationship can be thought of as subscribing to a newsletter for instance. I must register myself on the subscribers list in order to be notified of updates. Once I am notified I can take whatever action I choose, read, disregard, forward, etc... A connector is tasked with carrying events being signals or messages from one component to another. Connectors can have a range of multiplicities with components, ranging from one-to-one to one-to-many, or many-to-one. The advantage of using this style is that it encourages code reuse through low coupling and provides opportunities for evolution as new components are introduced. Asynchronous communication is handled extremely well within this type of design. All of the weaknesses that arise in this architectural style stem from the lack of control components have over event processing. Components are restricted to simply generating events while a framework is tasked with the event dispatching. Furthermore, respondents to events are not ordered, sometimes making global system analysis more challenging. Asynchronous events explicitly highlight this problem. ow can we ensure that at least one object has processed an event? Another weakness associated with this style is a problem arising from the exchange of data between components which can lead to a resources management challenge.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Process Control&lt;/b&gt;&lt;br /&gt;
This architectural style is particularly well suited for modeling physical control systems. In this model software interacts with peripheral devices like sensors and actuators in order to control physical systems. This architecture can be applied in real-time, continuous, adaptable (load balancing) and control system environments. The disadvantages of this architectural style are that the reuse of components are often confined to one particular domain of the application and it can become difficult to adapt when are two or more interdependent processes to control.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Architectural Views&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwZn128unOA7G7nmDxSwWNY4FgY5zBx5dLWmiMrG2nDJPV2A1jYVkuzYm6X-uWqeW9-T5ymEeAO_aJ6ehDrFqq5sqDyXL_rhwdANkum4B11XssvIqssWFKGXtYKZ1Tvm7KRRw1xaOWriW5/s1600/philippe_kruchtens_4_plus_1_view_model.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;158&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwZn128unOA7G7nmDxSwWNY4FgY5zBx5dLWmiMrG2nDJPV2A1jYVkuzYm6X-uWqeW9-T5ymEeAO_aJ6ehDrFqq5sqDyXL_rhwdANkum4B11XssvIqssWFKGXtYKZ1Tvm7KRRw1xaOWriW5/s200/philippe_kruchtens_4_plus_1_view_model.png&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;4+1 View Model&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;When analyzing the architecture of a system it is often most useful to consider the aspects of it relative to a particular view. A view is a fairly intuitive term in terms are architecture, it implies looking at something from a specific view-point. Naturally a single view-point cannot provide anyone with a complete picture, unless it is one dimensional, which large software projects are not.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&quot;4 + 1&quot; View Model of Architecture&lt;/b&gt;&lt;br /&gt;
This is one of the most popular view models conceived for software projects by &lt;a href=&quot;http://en.wikipedia.org/wiki/Philippe_Kruchten&quot;&gt;Phillipe Kruchten&lt;/a&gt;&amp;nbsp;in 1995.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th width=&quot;15%&quot;&gt;View&lt;/th&gt;&lt;th width=&quot;60%&quot;&gt;Description&lt;/th&gt;&lt;th width=&quot;25%&quot;&gt;Artifacts&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Logical View&lt;/td&gt;&lt;td&gt;The logical view is where the overall structure of the application is conveyed. Another way to characterize the logical view is to think of it as the interfaces to the environment in the most general of contexts.&lt;/td&gt;&lt;td&gt;- Package Diagrams&lt;br /&gt;
- Class Diagrams&lt;br /&gt;
- State Diagrams&lt;br /&gt;
- Interaction Diagrams&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Process View&lt;/td&gt; &lt;td&gt;The process view is used to paint a picture describing the underlying processes and tasks which are occurring within the system, as well as the channels of communication between them. The interrelationships amongst processes should be visible as well as the synchronization mechanisms.&lt;/td&gt; &lt;td&gt;- Class Diagrams&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- State Diagrams&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- Interaction Diagrams&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- Component Diagrams&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Deployment View&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;The deployment view, sometimes called the physical view, is used to describe the hardware and software setup that is required by the system. In this view we gain an appreciation of how the hardware and software components are combined to form the deployed product.&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- Deployment Diagrams&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Implementation View&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;The implementation view, sometimes called the development view, provides perspective on the software&#39;s organization. The components of the system as well as their inter-dependencies are outlined within this view. Libraries, sub-systems, executables, object files, etc. are all commonly documented components in this view. The relationships are denoted through containment and dependencies, thus providing a high-level vantage point for observing the software&#39;s organization.&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- Package Diagrams&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Use Case View&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;The use case view takes it&#39;s place prominently in the middle of the above 4+1 view model diagram, and rightfully so. It is the use cases which necessitated the system in the first place thus any model would be incomplete without it&#39;s &lt;a href=&quot;http://wordnetweb.princeton.edu/perl/webwn?s=raison%20d&#39;etre&quot;&gt;raison d&#39;être&lt;/a&gt;. Each system is designed to satisfy the needs of some target user, and the use case view elaborates on the systems utility from the users perspective. Note that not all use cases will be represented here, only those with the most architectural significance.&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;- Use Case Diagrams&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Siemens Four View Model&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0I8j1iSYODyp2Tv_IPkDGc8l4i6brSStqF5OaAcwq7dWg20p6syd9q6xnsePi6zFec6pWyI3AnvGlWr64xUHZdxS_6PUoPq6gCpSW_eOeUpihpR9_HZYANAPQy6uhcUWDWeiOy91UIXm/s1600/siemens+four+view+model.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;236&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhd0I8j1iSYODyp2Tv_IPkDGc8l4i6brSStqF5OaAcwq7dWg20p6syd9q6xnsePi6zFec6pWyI3AnvGlWr64xUHZdxS_6PUoPq6gCpSW_eOeUpihpR9_HZYANAPQy6uhcUWDWeiOy91UIXm/s320/siemens+four+view+model.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;This view model prescribes activities that should be carried out within each view. The activities are, global analysis, central analysis and final analysis.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Global Analysis&lt;/u&gt;&lt;br /&gt;
1) Analyze factors&lt;br /&gt;
2) Identify Issues&lt;br /&gt;
3) Create Strategies&lt;br /&gt;
&lt;br /&gt;
The purpose of global analysis is to identify issues early in the architecture so that strategies can be proposed to resolve them.&amp;nbsp;Factors are further decomposed into the following three categories: Product, Organizational, Technological.&amp;nbsp;Issues simply implies a potential problem or risk. Strategies alludes to a means by which an issue is resolved.&lt;br /&gt;
&lt;br /&gt;
Organizational factors can be further decomposed into the following top level groupings:&lt;br /&gt;
management, staff skills, process and development environment, development schedule and finally the development budget.&lt;br /&gt;
&lt;br /&gt;
Product factors are:&lt;br /&gt;
Functional features, user interface, performance, dependability, failure detection (reporting and recovery), service and product cost.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Design Principles&lt;/b&gt;&lt;br /&gt;
Definition of a good design:&amp;nbsp;A good design satisfies all of the requirements and passes all tests. It is also as simple as possible and conveys intent. There is no duplication and it&#39;s easy to understand, verify, extend and evolve.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Fundamental software design principles:&lt;/u&gt;&lt;br /&gt;
- Information hiding (Parnas)&lt;br /&gt;
- Protected Variations (Larman)&lt;br /&gt;
- Open-Closed Principle (Meyer)&lt;br /&gt;
- Separation of Concerns (Dijkstra, Parnas)&lt;br /&gt;
- High cohesion (GRASP)&lt;br /&gt;
- Low coupling (GRASP)&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Object Oriented Design Principles&lt;/u&gt;&lt;br /&gt;
Design based on responsibility assignment&lt;br /&gt;
- GRASP (Larman)&lt;br /&gt;
- Responsibility-Driven Design, RDD (Wirfs-Brock et. al.)&lt;br /&gt;
-&amp;nbsp;Class-Responsibility Collaboration&amp;nbsp;Card Design Technique (Kent Beck, Ward Cunningham)&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; -webkit-text-decorations-in-effect: none;&quot;&gt;General Responsibility Assignment Principles (GRASP)&lt;/span&gt;&lt;/u&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;td&gt;Controller&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Creator&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Indirection&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Information Expert&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;High Cohesion&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Low Coupling&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Pure Fabrication&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Protected Variations&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Polymorphism&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;Software Design Patterns&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;GoF Design Patterns&lt;/u&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;th&gt;Behavioral Patterns&lt;/th&gt; &lt;th&gt;Creational Patterns&lt;/th&gt; &lt;th&gt;Structural Patterns&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Chain of responsibility&lt;/td&gt; &lt;td&gt;Abstract Factory&lt;/td&gt; &lt;td&gt;Adapter&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Command&lt;/td&gt; &lt;td&gt;Builder&lt;/td&gt; &lt;td&gt;Bridge&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Interpreter&lt;/td&gt; &lt;td&gt;Factory Method&lt;/td&gt; &lt;td&gt;Composite&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Iterator&lt;/td&gt; &lt;td&gt;Prototype&lt;/td&gt; &lt;td&gt;Decorator&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Mediator&lt;/td&gt; &lt;td&gt;Singleton&lt;/td&gt; &lt;td&gt;Facade&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Memento&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;Flyweight&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Observer&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;Proxy&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;State&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Strategy&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Template Method&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Visitor&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;u&gt;Data Source Software Design Patterns&lt;/u&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Row Data Gateway (RDG)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Table Data Gateway (TDG)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Active Record&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Data Mapper&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;Document Object Model (DOM)&lt;/b&gt;&lt;br /&gt;
The document object model describes the structure of a document in a hierarchical context. Consider an HTML page, it is organized as a tree of tags, where the first tag is &amp;lt;html&amp;gt; and last tag is &amp;lt;/html&amp;gt;. Thus this tag is the root of the tree which is then followed by the &amp;lt;head&amp;gt; and &amp;lt;body&amp;gt; tags. More complicated hierarchies of tags arise when we begin to consider cascading style sheets. They allow stylistic hierarchies to be created for web content and stored&amp;nbsp;separately&amp;nbsp;from the content itself, providing a layer of indirection. The tags in an HTML page can be generalized to the concept of nodes of which the following types exist.&lt;br /&gt;
&lt;br /&gt;
DOM Node Types:&lt;br /&gt;
- Document&lt;br /&gt;
- Element&lt;br /&gt;
- Attribute&lt;br /&gt;
- Text&lt;br /&gt;
- Comment&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Architectural Definition Languages&lt;/b&gt;&lt;br /&gt;
This field is currently under continuous research and has not yet come to reach it&#39;s full potential. The concept here is to create a new higher level language that could serve to define both the structure and behavior of a program leading to executable code. I should point out that the scenario of producing executable code has not yet been completely realized. At the moment the best that can usually be done is creating the skeletons of the classes with method and attribute placeholders that would later be filled in. Some applications of code generation however have been quite successful, Boeing reported to have generated 75% of the code that was developed for their new 747. A closely related field is Model Driven Architecture (MDA) and Model Driven Design (MDD). The most notable of players in the market is IBM with it&#39;s Rose platform.&lt;br /&gt;
&lt;br /&gt;
There will be more to come on this post... very soon.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4227947461179976381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/02/software-architecture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4227947461179976381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4227947461179976381'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/02/software-architecture.html' title='Software Architecture'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU1ON9x7056qSPQ57ZC8esWJt1-A31jeGGb-Z536beXnPsqnuXSmFppoEH6h3wZCw2i1yubIFj-jLkQ2iAxewNvDsDlb3HK-ELbN15Ixdy62IuyMUnqXpMjqucDRoDmN6xSlNUmKF5Vzqb/s72-c/RationalUnifiedProcess.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-5171536401273622596</id><published>2011-02-17T21:16:00.005-05:00</published><updated>2011-04-11T03:29:54.745-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="software design"/><category scheme="http://www.blogger.com/atom/ns#" term="Usability engineering"/><category scheme="http://www.blogger.com/atom/ns#" term="user interaction experience"/><category scheme="http://www.blogger.com/atom/ns#" term="user interface design"/><category scheme="http://www.blogger.com/atom/ns#" term="UX"/><category scheme="http://www.blogger.com/atom/ns#" term="web design"/><title type='text'>Usability Engineering</title><content type='html'>&lt;b&gt;Overview&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXcMOPQ3GG6DP7AmGZP_4Af_yx0brAQ_QkcCOUNRj_LouqYVdQCiZS5wzn6msHfTTetBOowlpFAA7W-aoktuwcCBZScUfptoXIvI9dEx6anfe5b1ZOeD5grrao6zkkyRXuk9NbL2oRG7g/s1600/inter_dsciplinary_view.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;192&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXcMOPQ3GG6DP7AmGZP_4Af_yx0brAQ_QkcCOUNRj_LouqYVdQCiZS5wzn6msHfTTetBOowlpFAA7W-aoktuwcCBZScUfptoXIvI9dEx6anfe5b1ZOeD5grrao6zkkyRXuk9NbL2oRG7g/s320/inter_dsciplinary_view.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Human Computer Interaction and Interaction Design&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;The goal of usability engineering is to optimize the user experience within your applications. Ideally the customer should be able to interact with your product in a manner that feels most natural to them. This is much easier said than done when considering the diversity of an&amp;nbsp;applications user base, especially as the internet continues to proliferate. In order to maximize the quality of the user experience we will take an in depth look at the various activities that a software engineer should take in order to produce the highest quality application, in terms of user interaction and experience. The diagram on the right shows all of the different disciplines that relate to human computer interaction (HCI). As you can see there are a lot of professionals related to this practice, thus forming a well rounded team with specialists from as many disciplines as possible is a great way to generate good ideas within your team.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Good and Bad Designs&lt;/b&gt;&lt;br /&gt;
In order to appreciate good designs perhaps it would be helpful to first look at some bad designs. We have all seen bad designs before, the vending machine the scammed you, the remote control that was too complicated to use. Bad designs come along a lot more of then good designs since considerable effort is required to produce a design that is universally praised by a majority of the user base. &amp;nbsp;Basically a bad design does not lead the user naturally through workflows within the system, causing considerable confusion and frustration. A good design easily allows the user to recognize which actions need to be taken in order to achieve their goals. I would encourage you to&lt;a href=&quot;http://www.baddesigns.com/&quot;&gt; see some proof of bad design&lt;/a&gt; in everyday life so that you can see for yourself how rampant bad designs are.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Traits of a Good User Interface&lt;/b&gt;&lt;br /&gt;
- Helps the user quickly build a mental model of the entire system, not just one part.&lt;br /&gt;
- Enables the user to easily build a mental model of the application, leading to intuition for the users.&lt;br /&gt;
- Feels natural to user making it easy to learn how to use. Removes any surprises that may cause confusion.&lt;br /&gt;
- Feels like it&#39;s been tailored to the end-user.&lt;br /&gt;
- Allows the user to perform tasks efficiently.&lt;br /&gt;
- Meets the principal design goals of: usability, catering to different types of users, etc...&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Tangible Benefits of a Good User Interface&lt;/b&gt;&lt;br /&gt;
- Enhances the users productivity.&lt;br /&gt;
- Reduces the learning curve and associated costs.&lt;br /&gt;
- Enhances the end-users&#39; satisfaction.&lt;br /&gt;
- Improves the quality of the work performed by the users.&lt;br /&gt;
- Minimizes the the number of errors related to workflow processes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Things You Need to Know to be Able to Produce a Good UI Design&lt;/b&gt;&lt;br /&gt;
Since we are concerned with the performance of the system relative to our end-users, it is only natural that we focus on them. The following list represents traits of our users that can help guide our UI design choices.&lt;br /&gt;
&lt;br /&gt;
- Users profile, behavior, background, skill level, etc...&lt;br /&gt;
- The types of tasks that the user needs to perform.&lt;br /&gt;
- The context and social environment in which the system will be used.&lt;br /&gt;
- The limitations of what is suitable and&amp;nbsp;feasible&amp;nbsp;from a technological perspective.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The Difficulties of Producing a User Interface Design&lt;/b&gt;&lt;br /&gt;
Diversity amongst the users base as well as plethora of tasks which need to be performed compound to make the job of the UI designer that much more difficult. Additionally, understanding user requirements is not an easy process, as visible through the large number of software project failures. Additionally, when software begins it&#39;s lifetime, UI often takes a back seat since it&#39;s the last layer on the cake, although this is not recommended from a usability engineering perspective. The final and most decisive hurdle to most companies getting need to overcome in achieving a high quality UI is the cost associated with the process of researching, prototyping and testing.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;The Status Quo From a Software Engineers Perspective (Note this is not acceptable)&lt;/b&gt;&lt;br /&gt;
- Let us design for technology rather than for the end-user needs.&lt;br /&gt;
- Flashy graphics and nice colors to make up for bad design.&lt;br /&gt;
- Engineers obsess over program logic while users interact with the application visually.&lt;br /&gt;
-&amp;nbsp;Users make errors but we don&#39;t plan for them.&lt;br /&gt;
- Fix UI bugs with documentation&lt;br /&gt;
- Lack of time and budget, so improvements get pushed to the next release, perpetually in some cases.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tips for Understanding Your Users&#39; Needs&lt;/b&gt;&lt;br /&gt;
- Take into account your users strengths and weaknesses.&lt;br /&gt;
- Consider ways to help your users adopt more efficient work flows.&lt;br /&gt;
- Take the time to quantify what how to improve the quality of the user experience.&lt;br /&gt;
- Ask people what they want, and don&#39;t forget to listen to the answers.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;i&gt;&quot;you cannot design the user experience, you can only design for a user experience&quot;&lt;/i&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;The Interaction Design Process, Briefly&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Identify the needs and requirements for the suer experience.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Develop alternative designs to meet these goals.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Build interactive prototypes that can be evaluated.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Continuously evaluate what is being produced based on the quality of the user experience.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Core Characteristics of Interaction Design&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Users are involved throughout the development process&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- Specific usability and user experience goals must be identified, documented and agreed to by all parties.&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;- The design process occurs iteratively with time alloted for regular prototype evaluations.&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Important Terms for Usability Designers&lt;/b&gt;&lt;br /&gt;
- Visiblity, i.e. making the actions that a user can perform visible to them.&lt;br /&gt;
- Affordance, referring to an attribute of an object that allows people know how to use it, i.e. door handles, computer mice, etc...&lt;br /&gt;
- Conceptual model, this is a high-level description of how a system is organized and operates.&lt;br /&gt;
- Models, a simplification of some aspect of human-computer interaction intended to make it easier for designers to predict and evaluate alternative designs.&lt;br /&gt;
- Framework, a set of interrelated concepts and/or a set of specific questions.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Usability Principles (Nielson 2001)&lt;/b&gt;&lt;br /&gt;
- Visibility of system status&lt;br /&gt;
- Mach between system and the real world&lt;br /&gt;
- User control and freedom&lt;br /&gt;
- Consistency and standards&lt;br /&gt;
- Help users recognize, diagnose and recover from errors&lt;br /&gt;
- Error prevention&lt;br /&gt;
- Recognition rather than recall&lt;br /&gt;
- Flexibility and efficiency of use&lt;br /&gt;
- Aesthetic and minimalist design&lt;br /&gt;
- Help and documentation&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Understanding User Interaction&lt;/b&gt;&lt;br /&gt;
So far we&#39;ve highlighted the goals of user interaction design, and have seen what makes a good or bad design. We&#39;ll now switch our focus a bit towards understanding how to analyze the problem space (user requirements) so that when we do get to the point of designing out solution we will have a better idea of what problem we are trying to solve.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Analyzing the Problem Space&lt;/b&gt;&lt;br /&gt;
In order to effectively analyze the problem space we need to keep the following questions in mind.&lt;br /&gt;
- What do you want to create?&lt;br /&gt;
- What are your assumptions?&lt;br /&gt;
- &amp;nbsp;What are your claims?&lt;br /&gt;
- Will your solution effectively aid the user in achieving their goals, and how so?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Analyzing the Problem Space Related to Currently Implemented Solutions?&lt;/b&gt;&lt;br /&gt;
- Are there problems with an existing solution&lt;br /&gt;
- Why do you think there are problems within the existing solution?&lt;br /&gt;
- How do you think your proposed design ideas can overcome these issues?&lt;br /&gt;
- when designing for a new user experience how will the proposed design extend or change current workflows?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Creating a Conceptual Model&lt;/b&gt;&lt;br /&gt;
As defined above, the conceptual model is the high level design description of how the system will operate. This is extremely important to do at the beginning of the design process since it will help formulate the overall strategy for the solution to be. By establishing a conceptual model a lot of questions that may arise during the design process can be managed with the overall goal in mind allowing the designers to create a more cohesive solution.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Main Components of a Conceptual Model&lt;/b&gt;&lt;br /&gt;
- Major&amp;nbsp;metaphors&amp;nbsp;and analogies that are used to convey what the solution has been designed for and how it should be used.&lt;br /&gt;
- Concepts that users are exposed to in using the product.&lt;br /&gt;
- The relationships between the concepts.&lt;br /&gt;
- The mappings between the concepts and the user experience the product is designed to support.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Interface Metaphors&lt;/b&gt;&lt;br /&gt;
Using a metaphors in your design helps foster intuition amongst users. An effective metaphor allows the uses to grasp the underlying conceptual model with ease. It can also be an innovative way to make your application accessible to more users. A good metaphor is designed to be similar to some familiar physical entity, like a desktop. By likening your virtual solution to some physical entity you can allow the users to build their own intuition quickly about how the product performs.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Difficulties in Creating Interface Metaphors (Nielson, 1990)&lt;/b&gt;&lt;br /&gt;
- Break conventional and cultural rules (i.e. recycle bins on desktops).&lt;br /&gt;
- Can constrain designer in the way which they conceptualize the problem space.&lt;br /&gt;
- Conflict with design principles.&lt;br /&gt;
- Forces users to only understand the system in terms of the metaphor.&lt;br /&gt;
- Designer can inadvertently use bas existing designs and transfer the bad parts over.&lt;br /&gt;
- Limits the designers&#39; imagination in creating new conceptual models.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Interaction Types (M.I.C.E.)&lt;/b&gt;&lt;br /&gt;
The following is a categorization of the various interaction types.&lt;br /&gt;
- Instructing: Issuing commands using the keyboard, function keys and selecting options from a menu.&lt;br /&gt;
- Conversing: Interacting with the system as if having a conversation with it.&lt;br /&gt;
- Manipulating: Interacting with objects in a virtual or physical space by manipulating them.&lt;br /&gt;
- Exploring: Moving through a virtual environment or space.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Understanding Users&lt;/b&gt;&lt;br /&gt;
There are two types of cognition according to Norman (1993), experiential and reflective. Experiential cognition is defined as the type of cognitive exercise where a person is mindlessly interacting with his or her environment. Reflective cognition is when&amp;nbsp;&amp;nbsp;you deliberately think about an issue and make a decision about it. The reason that it is important to make this distinction is because each type of cognitive process requires different levels of technological support. One thing to keep in mind about all of this is that people have been proven to be much better at recognizing things than recalling them. Additionally, certain types of information are easier to recognize than others, such as pictures. This leads us to the concept of recall-directed memory versus recognition-based scanning. Suppose the user of your system was trying to go to a URL that they were recently at. The first attempt of the user is to remember the URL directly and simply type it in to the navigation bar. When this fails the user resorts to scanning his history for the proper URL since he was there just a few days ago. Although scanning takes longer than remembering something directly the end result was ultimately achieved. This shows us that it is important to provide your users with a couple different ways of locating items of interest in order to provide the most enjoyable user experience. A general strategy when &amp;nbsp;implementing some of these ideas into a UI is to use recognition rather than recall within menus, icons and consistently placed objects.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Theory of Action (Norman 1996)&lt;/b&gt;&lt;br /&gt;
The following theory is an approximation of the mental process which occurs in each of us when using software. This theory suggests that software should always provide it&#39;s users with meaningful responses in order to inform them whether or not their needs and intentions have been met.&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKZ3Ln2l_944hezBzoykoruWQ2CUFfx794FrV2A6loF801YClevhf-CAQ7XQGxNQDll3LCZdo91aZ0rV-NdeT6DaFGehWXCQ3R8JBNCyUc84ecgdMrkOpDXufjKjg1NfgGxsDE-jDKtm5-/s1600/gulf_of_execution_and_gulf_of_evaluation.JPG&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;189&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKZ3Ln2l_944hezBzoykoruWQ2CUFfx794FrV2A6loF801YClevhf-CAQ7XQGxNQDll3LCZdo91aZ0rV-NdeT6DaFGehWXCQ3R8JBNCyUc84ecgdMrkOpDXufjKjg1NfgGxsDE-jDKtm5-/s320/gulf_of_execution_and_gulf_of_evaluation.JPG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Bridging the gulfs of execution and evaluation, Norman 1986&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;1) Establish a goal&lt;br /&gt;
2) Form an intention&lt;br /&gt;
3) Specify an action sequence&lt;br /&gt;
4) Execute an action&lt;br /&gt;
5) Perceive the system state&lt;br /&gt;
6) Interpret the state&lt;br /&gt;
7) Evaluate the system state with respect to the goals and intentions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Data Gathering Techniques&lt;/b&gt;&lt;br /&gt;
1) Interviews&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;- Structured&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;- Semi-structured&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;- Unstructured&lt;br /&gt;
2) Focus Groups&lt;br /&gt;
3) Questionnaires&lt;br /&gt;
4) Observation&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;- Field&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp;- Controlled environment</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/5171536401273622596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/02/usability-engineering.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/5171536401273622596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/5171536401273622596'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/02/usability-engineering.html' title='Usability Engineering'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzXcMOPQ3GG6DP7AmGZP_4Af_yx0brAQ_QkcCOUNRj_LouqYVdQCiZS5wzn6msHfTTetBOowlpFAA7W-aoktuwcCBZScUfptoXIvI9dEx6anfe5b1ZOeD5grrao6zkkyRXuk9NbL2oRG7g/s72-c/inter_dsciplinary_view.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4424866021343443249</id><published>2011-01-31T01:33:00.005-05:00</published><updated>2011-01-31T01:50:54.582-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Apache"/><category scheme="http://www.blogger.com/atom/ns#" term="Java"/><category scheme="http://www.blogger.com/atom/ns#" term="Tomcat"/><title type='text'>Installing Tomcat In Ubuntu</title><content type='html'>&lt;b&gt;Quick how to guide for installing Tomcat in Ubuntu&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
1) make sure that you have the necessary Java SDK&#39;s installed. Use the following bash command:&lt;br /&gt;
dpkg --get-selections | grep sun-java&lt;br /&gt;
&lt;br /&gt;
You should have the following output:&lt;br /&gt;
sun-java6-bin&lt;br /&gt;
sun-java6-jdk&lt;br /&gt;
sun-java6-jre&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;If you get no results back then run the following command in the terminal to acquire the needed Java SDK&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$sudo apt-get install sun-java6-jdk&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
2) Now we&#39;re ready to download and install Tomcat available at &lt;a href=&quot;http://tomcat.apache.org/&quot;&gt;Apache&#39;s site&lt;/a&gt;. Check for the latest version download from the site or use the following command. Note this command is version specific so you may need to to adjust some numbers if you need a different version.&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$wget http://apache.hoxt.com/tomcat/tomcat-7/v7.0.6/bin/apache-tomcat-7.0.6.tar.gz &lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Now we will unpack the compressed file using this command:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$tar -xvzf apache-tomcat-7.0.6.tar.gz&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
It&#39;s a good idea to move the Tomcat folder to a permanent location and so we&#39;ll do the following:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$sudo mv apache-tomcat-7.0.6 /usr/local/tomcat&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
3) In order for Tomcat to run properly we need to set the JAVA_HOME variable in the .bashrc file which is located at: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$~/.bashrc&lt;/pre&gt;&lt;br /&gt;
We&#39;ll open up the bashrc file for editing using the following command:&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ sudo vi ~/.bashrc&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
and we now append the following line at the end of the file:&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;export JAVA_HOME=/usr/lib/jvm/java-6-sun&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
4) Before we can run Tomcat we&#39;ll need to log out of the current Ubuntu session since the changes that we made to the .bashrc file have not yet taken effect. We log back in and can now finally run Tomcat by executing the startup.sh script located in the tomcat/bin folder using the following terminal command:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$/usr/local/tomcat/bin/startup.sh&lt;/pre&gt;&lt;br /&gt;
*Note to stop Tomcat we use the following command in the terminal:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$/usr/local/tomcat/bin/shutdown.sh&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4424866021343443249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/installing-tomcat-in-ubuntu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4424866021343443249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4424866021343443249'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/installing-tomcat-in-ubuntu.html' title='Installing Tomcat In Ubuntu'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-5114482219816201850</id><published>2011-01-21T01:32:00.062-05:00</published><updated>2011-03-28T02:23:26.193-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="black box test"/><category scheme="http://www.blogger.com/atom/ns#" term="integration test"/><category scheme="http://www.blogger.com/atom/ns#" term="software testing"/><category scheme="http://www.blogger.com/atom/ns#" term="system test"/><category scheme="http://www.blogger.com/atom/ns#" term="unit test"/><category scheme="http://www.blogger.com/atom/ns#" term="white box test"/><title type='text'>Software Testing</title><content type='html'>&lt;b&gt;Why Testing Matters&lt;/b&gt;&lt;br /&gt;
Software testing is an important issue when trying to quantify the performance of a given program. As an engineer (to be) I know that I can only justify a claim with proof and so conducting software testing allows me the chance to prove my claims of quality.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Brief Basic Definitions&lt;/b&gt;&lt;br /&gt;
- Errors: An error is a mistake.&lt;br /&gt;
- Faults: A fault is the representation of an error. Good synonyms are bug and defect.&lt;br /&gt;
- Failures: A failure occurs when a fault executes. Failures only occur in an executable representation such as source code.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Errors of Commission versus Omission&lt;/b&gt;&lt;br /&gt;
An error of commission is when a programmer introduces a bug into the system through some faulty code. An error of omission occurs when a programmer neglects to include required functionality into the source code. Errors resulting from omission are much harder to catch and require that the testers be well informed about what functionality the system is expected to provide.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;A Graphical Representation of the Software Testing Life Cycle&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;A you can see in the diagram below, errors can be introduced into the testing life cycle at multiple points. An error that would be introduced during the requirements specification could be an error of omission, while errors in the design, coding and fault resolution stages are more likely to be errors of commission.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIGTxNXm6B9SGkkpn4fxKcACUpJo5ZlBa9jU2JA-lz3HoqFMte4DjaaJ_6rKMyVQtSW2IXoD3G8Qn70aUmum5HrQSoUW_ikL7OgIeJ1ljuX1YvHO1fl2_Dg6je1gEaemd2kF5EutlYT8Eu/s1600/Software_Testing_Life_Cycle.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;185&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIGTxNXm6B9SGkkpn4fxKcACUpJo5ZlBa9jU2JA-lz3HoqFMte4DjaaJ_6rKMyVQtSW2IXoD3G8Qn70aUmum5HrQSoUW_ikL7OgIeJ1ljuX1YvHO1fl2_Dg6je1gEaemd2kF5EutlYT8Eu/s320/Software_Testing_Life_Cycle.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Click to enlarge&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table border-style=&quot;dotted&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;     &lt;th colspan=&quot;2&quot;&gt;Test Cases&lt;/th&gt;  &lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Theory&lt;/b&gt;&lt;br /&gt;
In order to craft a well constructed test case we must define a test scenario from entry to exit. This involves us understanding the purpose of the test as well as any preconditions and inputs which are involved in the test. The expected outputs are equally important as we must have a baseline to compare the results of the test to, in order to determine if they have passed or not. The postconditions are also important to be certain that the test is a complete success. Test cases must be tracked through the software life-cycle for traceability purposes and must also have a well defined reason for being.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Precondition:&lt;/b&gt; something that must be true before the test case is executed&lt;br /&gt;
&lt;b&gt;Postcondition:&lt;/b&gt; some condition that must be true after the test case has executed.&lt;/td&gt; &lt;td&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;     &lt;th colspan=&quot;4&quot;&gt;Test Case Template&lt;/th&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Test Case ID&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Purpose&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Preconditions&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Inputs&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;br /&gt;
&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Expected Outputs&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;2&quot;&gt;Postconditions&lt;/td&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt;   &lt;td colspan=&quot;4&quot;&gt;Execution History&lt;/td&gt;  &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Date&lt;/td&gt;&lt;td&gt;Result&lt;/td&gt;&lt;td&gt;Version&lt;/td&gt;&lt;td&gt;Run By&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;Pass/Fail&lt;/td&gt;&lt;td&gt;&lt;br /&gt;
&lt;/td&gt;&lt;td&gt;&lt;br /&gt;
&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&lt;b&gt;Test Case Design&lt;/b&gt;&lt;br /&gt;
&quot;A test case is a set of instructions designed to uncover a particular type of error or defect in the software system by inducing failure.&quot;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What a Venn Diagram Can Tell Us&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDQoitauoB7CRSPCxH7uPjLCJmJobtXbaEu6da2YWgQtdpSRBS1F8BsCeoaZPkd2QHxAAekV-roF9h5tICMyeDDgKRyqJQeglMZ5BumuZAQnKQtof6pEQhET6RSc7_d39GwM7ySR4Pvbq9/s1600/venn_diagram_image.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;170&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDQoitauoB7CRSPCxH7uPjLCJmJobtXbaEu6da2YWgQtdpSRBS1F8BsCeoaZPkd2QHxAAekV-roF9h5tICMyeDDgKRyqJQeglMZ5BumuZAQnKQtof6pEQhET6RSc7_d39GwM7ySR4Pvbq9/s200/venn_diagram_image.jpg&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;In the Venn Diagram we see two circles, one labelled A and the other B. Let&#39;s assume that circle A refers to the specified or expected behavior of an application, while circle B refers to the observed behavior of the same application. The intersection of A and B is where the requirements meet the programmed behavior. The portions of the circle in A which are not included in the intersection are requirements which have yet to be programmed and can be considered errors of omission. The areas of circle B which are not included in the intersection are equally a problem as they represent waisted effort on the part of the programmers since they have implemented functionality which has not been specified.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Testing Objectives&lt;/b&gt;&lt;br /&gt;
According to the Software Engineering Body of Knowledge (SWEBOK), the objectives of testing are the following:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;- Acceptance / &amp;nbsp;Qualification&lt;br /&gt;
&amp;nbsp;- Installation&lt;br /&gt;
&amp;nbsp;- Alpha &amp;amp; Beta&lt;br /&gt;
&amp;nbsp;- Conformance / Functional / Correctness&lt;br /&gt;
&amp;nbsp;- Reliability&lt;br /&gt;
&amp;nbsp;- Regression&lt;br /&gt;
&amp;nbsp;- Performance&lt;br /&gt;
&amp;nbsp;- Stress&lt;br /&gt;
&amp;nbsp;- Back to back&lt;br /&gt;
&amp;nbsp;- Recovery&lt;br /&gt;
&amp;nbsp;- Configuration&lt;br /&gt;
&amp;nbsp;- Usability&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Structural Versus Functional Testing&lt;/b&gt;&lt;br /&gt;
Structural testing is used to create test cases based on the implemented code base, while functional testing focuses on testing the system from users point of view with absolutely no knowledge of how any of the functionality is implemented in code. Structural testing relies heavily on graph theory while functional testing relies more so on intuition and clearly stated functional requirements.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;Types of Testing&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Structural Testing&lt;/th&gt;&lt;th&gt;Functional Testing&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Unit testing&lt;/td&gt;&lt;td&gt;Boundary value testing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Integration testing&lt;/td&gt;&lt;td&gt;Equivalence class testing&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;System testing&lt;/td&gt;&lt;td&gt;Truth table testing&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;White-Box Testing&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;This simply refers to testing methods which look &quot;under the hood&quot;. The system is tested from the inside by verifying code, rather than testing by simply observing outputs.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;Black-Box Testing&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;This type of testing is commonplace in the field of control systems. A black-box test is a test where the output of some input is observed for any errors. Thus this is a type of functional testing where we are really trying to verify if the system performs as expected for a given range of inputs. We have a concept of the expected output for each input and are making sure that it always corresponds. An example of black-box testing is system testing, acceptance testing, etc...&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Unit Testing&lt;/b&gt;&lt;br /&gt;
The purpose of a unit test is to test a small subset or component of code in order to make sure it performs as expected. Unit testing occurs throughout the coding process, ideally before any code is even written. Test driven development (TDD) is the practice of writing unit tests before writing the code necessary to pass the tests. This offers the programmer the advantage of conceiving the code they intend to write before actually writing it. I know this may sound silly but it&#39;s actually extremely helpful. Once you have written a test case for some code, you have actually already began writing the code that you need to pass the test. I am an advocate of this type of testing and would recommend TDD to programmers with any amount of coding experience.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Integration Testing&lt;/b&gt;&lt;br /&gt;
Integration testing is similar to unit testing although this time the snippets of code being tested are not as simple. The goal with integration testing is to see how all of the moving parts fit together. Thus the integration test case&#39;s primary goal is to validate the interactions between components. Note that the components should have all been tested previously within independent unit tests.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;System Testing&lt;/b&gt;&lt;br /&gt;
This is a higher level of testing than either the unit or integration tests. This type of testing is almost analogous to user acceptance testing. System testing is done at the system boundary level and it&#39;s primary goal is to evaluate the functionality of the system in terms of it&#39;s expected performance during it&#39;s intended use.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Regression Testing&lt;/b&gt;&lt;br /&gt;
Regression testing is used to ensure that newly written code is compatible with previously written code. The way this compatibility is measured is by running previously written tests on the newly expanded code base ensuring that no new bugs have been introduced into the system as the result of the additional code. Naturally there are limits to testing and every test can&#39;t possible be re-run every time the code has been updated, although it is expected that a sub-set of the tests which passed previously should be re-run.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;The Law of Conservation of Bugs&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&quot;The number of bugs remaining in a system is proportional to the number of bugs already fixed.&quot;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Key Issues in Testing&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;- The oracle problem&lt;br /&gt;
&amp;nbsp;- Limitations of testing&lt;br /&gt;
&amp;nbsp;- The problem of infeasible paths&lt;br /&gt;
&amp;nbsp;- Test selection criteria / Test adequacy criteria&lt;br /&gt;
&amp;nbsp;- Test effectiveness / Objectives for testing&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Oracle Problem&lt;/b&gt;&lt;br /&gt;
The oracle problem starts with a tale of 100 blue eyed people on an island and ends with them all being dead 100 days later. To summarize the story, everyone on the island does not know their own eye color nor can anyone else tell them. Everyone knows what color eyes everyone else has though, since they can all see. One day an oracle shows up on the island and tells everyone that some people have blue eyes. This is bad news because if you find out that you have blue eyes you must kill yourself alone at midnight. To make a long story short, everyone looks around and sees tons of other people with blue eyes thinking that they themselves don&#39;t. 100 days later everyone realizes that no one else has killed themselves meaning that they must be the ones with the blue eyes and so the tale comes to an end. On the surface this problem was not easy to relate to software testing and so I started a&amp;nbsp;&lt;a href=&quot;http://stackoverflow.com/questions/4789456/the-oracle-problem-as-it-relates-to-testing&quot;&gt;post at StackOverflow&lt;/a&gt;. Here is a quote from the post with the best explanation I got regarding the problem as it relates to testing.&amp;nbsp;&quot;&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse; font-family: Arial, &#39;Liberation Sans&#39;, &#39;DejaVu Sans&#39;, sans-serif; font-size: 14px; line-height: 18px;&quot;&gt;I don&#39;t consider it (the oracle problem) a very good analogy, but the idea is that you can test a piece of software against something, some standard, to see if it gives the correct answer. The standard might be another piece of software, or the same software in a previous run, or theoretical results, or whatever. But how do we know the standard is correct? It would be really good to have a standard which is correct, and which everyone knows is correct, and which&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse; font-family: Arial, &#39;Liberation Sans&#39;, &#39;DejaVu Sans&#39;, sans-serif; font-size: 14px; line-height: 18px;&quot;&gt;&lt;em style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; font-style: italic; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;everyone knows&amp;nbsp;&lt;/em&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;border-collapse: collapse; font-family: Arial, &#39;Liberation Sans&#39;, &#39;DejaVu Sans&#39;, sans-serif; font-size: 14px; line-height: 18px;&quot;&gt;everyone knows is correct, and so on.&lt;/span&gt;&quot; I think that this response is self explanatory once you&#39;ve understood the oracle problem.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Limitations of Testing&lt;/b&gt;&lt;br /&gt;
Since everything has it&#39;s limits in life why shouldn&#39;t testing. Some programming problems have an infinite number of solutions and so it would be impossible to test every single possible outcome within a reasonable amount of time. Take any piece of code with an infinite loop and try to figure out how you could test every possible outcome (without running out of time first, possibly on your life). &lt;i&gt;Combinatorial explosion&lt;/i&gt;&amp;nbsp;is another instance where testing can get out of control, say 4 inputs exist with 5 possible values, 4&lt;sup&gt;5&lt;/sup&gt; combinations exist.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The Problem of Infeasible Paths&lt;/b&gt;&lt;br /&gt;
Not every line of code is necessarily reachable. Such paths are referred to infeasible and represent another limitation of testing. A basic example of this would be a line of code which could never be reached because of some Boolean condition in an IF statement which would never become true.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Functional Testing&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;b&gt;Boundary Value Testing&lt;/b&gt;&lt;br /&gt;
Any computer program can be considered to be a mathematical function with values mapping from domain to the range. As an example, consider the input of the program to be it&#39;s domain and the range of the program to be it&#39;s output. While conventionally in boundary value testing an emphasis is placed on the input values, knowing what the expected output should be is an excellent way to squeeze more value out of the tests. Boundary value testing is an excellent way of getting rid of the pesky &quot;off by 1&quot; errors loops are prone to, it&#39;s also good way to uncover errors that exist at the extreme values of inputs.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;How to Determine the Boundaries&lt;/b&gt;&lt;br /&gt;
A simple formula is available for us to come up with the boundaries of a certain variable. We will always define the following five values to be tested for each variable of interest:&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVl98UWpvxqiVdRifnqhv432OCLqUJJzKvC7-AjuV82O9N3MeazEIt-JFwNMGXEiMQdJzZ8qN1Tvr98HnXqslfXh3VsPoTNiOVZsQxWFth6qLp4-MrUd64XwY6PVUsb5ozobyEOGzlBNM/s1600/boundary+value+testing.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;166&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTVl98UWpvxqiVdRifnqhv432OCLqUJJzKvC7-AjuV82O9N3MeazEIt-JFwNMGXEiMQdJzZ8qN1Tvr98HnXqslfXh3VsPoTNiOVZsQxWFth6qLp4-MrUd64XwY6PVUsb5ozobyEOGzlBNM/s200/boundary+value+testing.gif&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Boundary values on a graph&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;&quot;&gt;Value&lt;/div&gt;&lt;/th&gt;&lt;th&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Denoted as&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Minimum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;min&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just above minimum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;min+&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Nominal value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;nom&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just below maximum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;max-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Maximum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;max&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
The single fault assumption, from reliability theory, provides a critical enhancement to the process of boundary value analysis by proposing that rarely will a failure be the result of the simultaneous occurrence of more than one fault. This allows us to restrict the number of test cases necessary by holding all but one variables at their nominal values while testing the five possible values for a second variable. For some clarification here I&#39;ll list the set of test cases that would be needed to test two input variables, a and b.&lt;br /&gt;
&lt;br /&gt;
set of test cases T = {&amp;lt;A&lt;sub&gt;nom&lt;/sub&gt;, B&lt;sub&gt;min&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;nom&lt;/sub&gt;, B&lt;sub&gt;min+&lt;/sub&gt;&amp;gt;, &amp;lt;A&lt;sub&gt;nom&lt;/sub&gt;, B&lt;sub&gt;nom&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;nom&lt;/sub&gt;, B&lt;sub&gt;max-&lt;/sub&gt;&amp;gt;,&lt;br /&gt;
&amp;lt;A&lt;sub&gt;nom&lt;/sub&gt;, B&lt;sub&gt;max&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;min&lt;/sub&gt;, B&lt;sub&gt;nom&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;min+&lt;/sub&gt;, B&lt;sub&gt;nom&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;max-&lt;/sub&gt;, B&lt;sub&gt;nom&lt;/sub&gt;&amp;gt;,&amp;nbsp;&amp;lt;A&lt;sub&gt;max&lt;/sub&gt;, B&lt;sub&gt;nom&lt;/sub&gt;&amp;gt;}&lt;br /&gt;
&lt;br /&gt;
Using our math skills we can come up with a general equation for the number of test cases needed to conduct boundary value testing for any number of variables.&lt;br /&gt;
&lt;br /&gt;
Y = the number of variables&lt;br /&gt;
Total number of unique test cases = (4 x Y) + 1&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;# of variables&lt;/th&gt;&lt;th&gt;Equation&lt;/th&gt;&lt;th&gt;# Test Cases&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px;&quot;&gt;(4 x 2) + 1&lt;/span&gt;&lt;/td&gt;&lt;td&gt;9&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;(4 x 3) + 1&lt;/td&gt;&lt;td&gt;13&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;(4 x 10) + 1&lt;/td&gt;&lt;td&gt;41&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
As you can see the number of test cases rises linearly with the number of variables and so it is recommended to use automated tools to conduct this task most efficiently. Here is a link to a list of &lt;a href=&quot;http://java-source.net/open-source/testing-tools&quot;&gt;open source Java testing tools&lt;/a&gt;, some of which can be used to conduct boundary value testing in an automated fashion.&lt;br /&gt;
&lt;br /&gt;
When no clear bounds exist for a variable we must artificially impose bounds on the variable.Although theoretically this seems unfair practically it isn&#39;t. Your computer can only perform calculations on a number of a finite size thus it makes sense to make a cap somewhere. Sometimes boundary value testing doesn&#39;t make as much sense, especially when it comes to Boolean variables thus it&#39;s use is limited in it&#39;s ability to provide value to the testing of an application. Boundary value testing works best when the program that it&#39;s testing is a function of many independent physical quantities. To put this statement into context, suppose we were testing a program that tests whether a date is valid. According to the above formula for formulating the test cases it is clear that the mechanically formed tests would capture the end of month and end of year date faults but it might not capture all of the leap year faults. When dealing with physical quantities the bounds are much more important, like length, height, speed, force. This is when boundary value testing is most appropriate.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Robustness Testing&lt;/b&gt;&lt;br /&gt;
Robustness testing is a small improvement over boundary value testing. If you noticed in boundary value testing we only approached the extreme valid numbers of a function, but never exceeded them. This is the value that robustness testing brings to the table. We&#39;ll add two more test cases to every variable to capture the programs behavior as it exceeds the upper and lower permissible bounds.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;&quot;&gt;Value&lt;/div&gt;&lt;/th&gt;&lt;th&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Denoted as&lt;/div&gt;&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just below minimum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;min-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Minimum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;min&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just above minimum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;min+&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Nominal value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;nom&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just below maximum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;max-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Maximum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;max&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Just above maximum value&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;max+&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;i&gt;&amp;nbsp;This type of testing directs your attention towards exception handling.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Worst-Case Testing&lt;/b&gt;&lt;br /&gt;
In worst-case testing we push the envelope even further by introducing even more test cases. This time we revert back to the original five values for each variable as we had in boundary value testing, only this time we take the Cartesian product of the five test cases per variable, resulting in 5&lt;sup&gt;n&lt;/sup&gt; test cases in total. We&#39;ve discarded the single fault reliability theory in this case and augmented the number of test cases considerably. If you want to take worst-case testing even further you could combine it with robustness testing and up your number of test cases to 7&lt;sup&gt;n&lt;/sup&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Special Value Testing&lt;/b&gt;&lt;br /&gt;
This is the most intuitive of all of the testing methods we&#39;ve discussed so far as it relies on the intuition of the programmer to devise clever test to challenge the &quot;soft spots&quot; in the program. The challenge in promoting this type of testing is that it&#39;s outcome is largely dependent on the abilities of the programmer, which can be another potential source of error. Since the other tests we looked at don&#39;t encapsulate domain specific knowledge that the programmers may have, special testing can often be very effective at isolating problems in code.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Equivalence Class Testing&lt;/b&gt;&lt;br /&gt;
Since boundary value testing doesn&#39;t satisfy our need for complete without redundancy we need something a little bit more powerful to help us.Boundary value testing can be thought of as forming the lines around a box, whereas equivalence class testing takes the same box yet breaks it apart into puzzle pieces that form the whole. The value of breaking the box into pieces is that each of piece can be thought of a set of values with something in common. This is a powerful notion as it allows us to further divide the square into logical components which form a set of data which can be used for testing. Thus by taking one element from each set (puzzle piece) we can form a more comprehensive set of test that eliminate redundancies and provides a sense of completeness, since an element from each puzzle piece is tested, and all of the puzzle pieces together form the entire square. By choosing your equivalence classes wisely you can reduce the number of test cases needed while improving the quality of them greatly.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Weak Normal Equivalence Class Testing&lt;/b&gt;&lt;br /&gt;
In weak normal equivalence class testing we only use one value from each equivalence class in a test case. By using one value only from each equivalence class we are once again employing the single fault assumption. The number of test cases generated using this form is testing is always equivalent to the number of equivalent classes defined.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Strong Normal Equivalence Class Testing&lt;/b&gt;&lt;br /&gt;
In strong normal equivalence class testing we use the multiple fault assumption in lieu of the&amp;nbsp;single fault assumption. This provides a sense of completeness in our testing since we take the Cartesian product of all of equivalence classes. The result of taking the cross product will yield a result similar to that which a truth table would produce.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Weak Robust Equivalence Class Testing&lt;/b&gt;&lt;br /&gt;
Since the name (weak and robust) is counter intuitive we&#39;ll break it down make some sense of it. The robust part, as before, alludes to the consideration of invalid values, while the weak part refers back to the single fault assumption. Thus to craft our test cases for the valid inputs we will use one value from each valid &amp;nbsp;equivalence class, just as we did in the weak normal equivalence class testing. For the invalid inputs we will associate one invalid input to every equivalence class (note the single fault assumption). Weak robust equivalence class testing can often become awkward in modern strongly typed languages. It was a much more popular form of testing historically when languages like COBOL and FORTRAN dominated the scene. In fact, strongly typed languages were developed to address the faults often uncovered by weak robust equivalence class testing.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Strong&amp;nbsp;Robust&amp;nbsp;Equivalence Class Testing&lt;/b&gt;&lt;br /&gt;
This time the name is not as confusing as it is redundant. As usual the robust part of the title refers to the consideration of invalid inputs, while the strong part implies the multiple fault assumption. This time we derive our test cases from the Cartesian product of each element from the equivalent classes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Decision Table-Based Testing&lt;/b&gt;&lt;br /&gt;
Of all the functional testing methods seen so far, decision tables offer the most complete form of testing since they are the most rigorous. Two types of decision tables exist, limited entry decision tables and extended entry decision tables. The difference between the two is the type of conditions that a value can take. In a limited entry decision table only binary conditions can apply, while in an extended entry decision table three or more conditions may apply. To identify the test cases from a decision table we interpret the conditions as inputs to our program and actions as the outputs. Recall that in a binary decision table the total number of rows necessary is 2&lt;sup&gt;n&lt;/sup&gt;, where n is the number of variables being tested. So two variables with binary conditions yields a truth table with 4 rows and 2 columns and three variables yields a table with 8 rows and 3 columns. Use decision table testing for programs that have a lot of decisions being made.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Here&#39;s a little graphical review for you to crystallize the trends of effort and sophistication involved in the functional testing methods seen.&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr9lrgISQLvPeMRSP1bnYrXg6p7Ig8Yu6jbBFZk0L-w93fNqXba5Kpa58lM2x8Kvv_iWTQOLXIJLPaSgLTrIeT-bh_WkmjiHtFxl2wrX1DmfjQ-618fCmUHQ0tJI2YdjRWb7rAOoqlSJIZ/s1600/trendline+of+test+cases+per+testing+method.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr9lrgISQLvPeMRSP1bnYrXg6p7Ig8Yu6jbBFZk0L-w93fNqXba5Kpa58lM2x8Kvv_iWTQOLXIJLPaSgLTrIeT-bh_WkmjiHtFxl2wrX1DmfjQ-618fCmUHQ0tJI2YdjRWb7rAOoqlSJIZ/s400/trendline+of+test+cases+per+testing+method.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3eswQ9LwICco56-SUqJhzAoLbQ09UdSy8WIrWRSyOIm-29msugWZvmMnQz6HIo0xjw_FWuuCK4KR-Hm19q3dx4RhSPcl47tsSIhVrfRxqVahIobZ1rsMiQ2eZhN64gPR-rbnY25ZMnRdB/s1600/trendline+of+test+cases+identification+per+testing.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;236&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3eswQ9LwICco56-SUqJhzAoLbQ09UdSy8WIrWRSyOIm-29msugWZvmMnQz6HIo0xjw_FWuuCK4KR-Hm19q3dx4RhSPcl47tsSIhVrfRxqVahIobZ1rsMiQ2eZhN64gPR-rbnY25ZMnRdB/s400/trendline+of+test+cases+identification+per+testing.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;How to Determine What Type of Functional Testing is Most Appropriate&lt;/b&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;td&gt;C1&lt;/td&gt; &lt;td&gt;Variables (P, physical; L, logical)&lt;/td&gt; &lt;td&gt;P&lt;/td&gt; &lt;td&gt;P&lt;/td&gt; &lt;td&gt;P&lt;/td&gt; &lt;td&gt;P&lt;/td&gt; &lt;td&gt;P&lt;/td&gt; &lt;td&gt;L&lt;/td&gt; &lt;td&gt;L&lt;/td&gt; &lt;td&gt;L&lt;/td&gt; &lt;td&gt;L&lt;/td&gt; &lt;td&gt;L&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;C2&lt;/td&gt; &lt;td&gt;Independent variables?&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;C3&lt;/td&gt; &lt;td&gt;Single fault assumption?&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;-&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;-&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;C4&lt;/td&gt; &lt;td&gt;Exception handling?&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;-&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;Y&lt;/td&gt; &lt;td&gt;N&lt;/td&gt; &lt;td&gt;-&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A1&lt;/td&gt; &lt;td&gt;Boundary Value Analysis&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;br /&gt;
&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A2&lt;/td&gt; &lt;td&gt;Robustness Testing&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A3&lt;/td&gt; &lt;td&gt;Worst-Case Testing&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A4&lt;/td&gt; &lt;td&gt;Robust Worst-Case&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A5&lt;/td&gt; &lt;td&gt;Weak Robust Equivalence Class&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A6&lt;/td&gt; &lt;td&gt;Weak Normal Equivalence Class&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A7&lt;/td&gt; &lt;td&gt;Strong Normal Equivalence Class&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;A8&lt;/td&gt; &lt;td&gt;Decision Table&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;&lt;/td&gt; &lt;td&gt;X&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large; font-weight: bold;&quot;&gt;Structural Testing&lt;/span&gt;&lt;br /&gt;
&lt;hr /&gt;The key trait of structural testing is that it is based on the source code of the application instead of on it&#39;s specifications. Since structural testing is based on the implementation the most basic step we can take to define a program mathematically is to create a program graph.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Program Graph&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGFKiF6omsb5rCD3kKb5BH7yv31GLk0ouuCjes4DiVxEdlhGYETSlCTnZQ-1BplCoIB7XcKP1W1KdHUtVNNB3XaLLPaizW6Bg0y8LUCVpEUGqnWB6Y53x3KsZRrItb5GUWhDoM46X3bP8P/s1600/Program+Graph.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGFKiF6omsb5rCD3kKb5BH7yv31GLk0ouuCjes4DiVxEdlhGYETSlCTnZQ-1BplCoIB7XcKP1W1KdHUtVNNB3XaLLPaizW6Bg0y8LUCVpEUGqnWB6Y53x3KsZRrItb5GUWhDoM46X3bP8P/s320/Program+Graph.jpeg&quot; width=&quot;155&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Click to enlarge&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;A program graph is a directed graph representing a program whereby the nodes in the graph represent statement fragments while the edges represent the control flow. So in the graph depicted on the right side we have two variables declared immediately, i and j, followed by a control statement which leads to two different states. From there we proceed to exit the control statement and head to the final statement where the value of j is returned. Loops in code can also be easily graphed using the same principles which we have applied here. A loop will always contain a control statement that will verify whether or not the loop should continue, and from there you might either return into the loop or head towards another state unrelated to the loop. No matter what type of control flow statement you face rest assured that the same principles apply in graphing them. The only thing you need pay attention to is at which point in the code the decision making occurs. Note that normally in a Program Graph you would not label the nodes with actual statements from the program but more likely a statement number (or line number, when only one statement appears on each line).&amp;nbsp;Here is a tiny sample of how to model a For-loop.&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2gbWyZHqWSY7E2KKW7KcuXOxz748drTr2M1zt4Tt_kj767w90Yu1-g6f8YP7iN3WLInzgbmyjQ96259PlGZvbWh_MYRMjgOqz3mfOrItbMYg7WEuK_q_-Zp78YfVlWWimMHVRu4FWQi7n/s1600/For+Loop.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; display: inline !important; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;44&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2gbWyZHqWSY7E2KKW7KcuXOxz748drTr2M1zt4Tt_kj767w90Yu1-g6f8YP7iN3WLInzgbmyjQ96259PlGZvbWh_MYRMjgOqz3mfOrItbMYg7WEuK_q_-Zp78YfVlWWimMHVRu4FWQi7n/s320/For+Loop.jpeg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Click to enlarge&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;DD-Paths&lt;/b&gt;&lt;/div&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt9CrY6G7ENZ8BoCxpvZjNcd9JXpAoSXxysOXhxZnqcFF1IsZIhsHlEyLFmwNWL-hYuOmVCZAAMT5tcHXn9jp4YKFPoIwLlMUlH95PBQ5Ff5uKK7wSn-JQjY9a6OiDBYRg4OfuqFH3LSQ1/s1600/DD-Path+Graph.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt9CrY6G7ENZ8BoCxpvZjNcd9JXpAoSXxysOXhxZnqcFF1IsZIhsHlEyLFmwNWL-hYuOmVCZAAMT5tcHXn9jp4YKFPoIwLlMUlH95PBQ5Ff5uKK7wSn-JQjY9a6OiDBYRg4OfuqFH3LSQ1/s320/DD-Path+Graph.jpeg&quot; width=&quot;248&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Click to enlarge&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;Decision to Decision Paths are the most widely used form of structural testing, created by Miller in 1977. What distinguishes DD-Path graphs from Program Graphs is the level of granularity with which the program is decomposed. In a program graph every statement within the program is given it&#39;s own node. In a DD-Path graph only nodes that lead to decisions (control flow) are given their own nodes. Thus we can now appreciate the original description provided by Miller: a path begins with the &quot;outway&quot; of a decision statement and ends with the &quot;inway&quot; of the next decision statement. In order to demonstrate this concept I&#39;ve converted the above Program Graph into a DD-Paths graph. Note that I&#39;ve re-labelled the vertices with numbers representing the statement number based on the order of the statements in the Program Graph. This follows a more conventional style of labeling nodes seen in most examples and texts.&amp;nbsp;In the DD-Paths graph illustrated on the right there are two unique (linearly&amp;nbsp;independent) paths that can be enumerated, 3,4,6,7 and 3,5,6,7.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Formal Definition of DD-Paths&lt;/b&gt;&lt;br /&gt;
A DD-Path is a sequence of nodes in a program graph such that:&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Case 1: It consists of a single node with indegree = 0.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Case 2: It consists of a single node with outdegree = 0.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Case 3: It consists of a single node with indegree &amp;gt;= 2 or outdegree &amp;gt;= 2.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Case 4: It consists of a single node with indegree = 1 and outdegree = 1.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Case 5: It is a maximal chain of length &amp;gt;= 1.&lt;br /&gt;
&lt;br /&gt;
This formal definition on the surface is a little hard to appreciate so we&#39;ll decompose it and find out what it means. Case 1 refers to the fact that every graph must have a starting node, which does not have any edges directed in towards it. Case 2 establishes that the graph must have a terminal node, which does not have any edges directed away from it.&amp;nbsp;Case 3 states that a complex node must not be contained within more than one DD-Path. Case 4 is needed to enforce against a short path while also preserving the one-fragment, one-DD-path &amp;nbsp;principle. Case 5 is the case in which a DD-Path is the is a single-entry and single-exit chain. The maximal part of case 5 is used to determine the final node of a normal chain.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;So What is a DD-Path Graph Good For?&lt;/b&gt;&lt;br /&gt;
The insight that DD-Path graphs bring to programmers is the ability to quantify testing coverage precisely. This is rather important when attempting to determine the extent to which code has been tested, and as we&#39;ve noted earlier there are limitations to testing (Hint: testing loops). According to E.F. Miller (1991), when DD-Path coverage &amp;nbsp;is attained by a set of test cases, roughly 85% of all faults are revealed. This is a very significant statistic and should act as motivation for every software engineer to enforce even the most basic testing methods as the benefits far outweigh the effort.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;McCabe&#39;s Basis Path Method&lt;/b&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeWxGWEbgEpoqhnf1qxFqg9vH6ITIOoEM0dQaKZNZRxwa_RjpbwmsPYnDq_Xfz_D3HCfqSiEuoyIhs0wDOHy8BrXhUZON69AvkQvWCtC4xRI8ooaf-D_YdvCeDVDfMS3ei6Wv1nEsqyTh/s1600/McCabes+control+graph.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeWxGWEbgEpoqhnf1qxFqg9vH6ITIOoEM0dQaKZNZRxwa_RjpbwmsPYnDq_Xfz_D3HCfqSiEuoyIhs0wDOHy8BrXhUZON69AvkQvWCtC4xRI8ooaf-D_YdvCeDVDfMS3ei6Wv1nEsqyTh/s200/McCabes+control+graph.jpeg&quot; width=&quot;156&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;V(G) = 10 - 7 + 2(1) = 5&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;In the 1970&#39;s, Thomas McCabe applied some breakthroughs in graph theory related to the cyclomatic number of a strongly connected graph to computer science in order to determine the number of linearly independent paths in the graph. Thus the cyclomatic complexity of a graph is equal to the number of linearly independent paths in the graph. The graph depicted on the right is a classic example cited in many texts. Since the graph on the right is not strongly connected we will need to add an edge from node G back to A in order to apply the cyclomatic complexity (denoted V(G)) calculation.&lt;br /&gt;
&lt;br /&gt;
Cyclomatic complexity of a weakly connected graph:&lt;br /&gt;
V(G) = e - n + 2p&lt;br /&gt;
e is the number of edges&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCxA6qgQhylq_TiBZWUygd81xaGfc8X3mnjlm13EAhI6d_ervGCcgVlKw8Gska_PBi9JAjvKofZ6bADkD1saARsr0FXKISIKfwF5zucRJ1FXruVozbABnA3BKSauCW63HCrds-E-lopO_N/s1600/McCabes+control++completed+graph.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;188&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCxA6qgQhylq_TiBZWUygd81xaGfc8X3mnjlm13EAhI6d_ervGCcgVlKw8Gska_PBi9JAjvKofZ6bADkD1saARsr0FXKISIKfwF5zucRJ1FXruVozbABnA3BKSauCW63HCrds-E-lopO_N/s200/McCabes+control++completed+graph.jpeg&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;V(G) = 11 - 7 + 1 = 5&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;n is the number of nodes&lt;br /&gt;
p is the number of connected regions&lt;br /&gt;
&lt;br /&gt;
Cyclomatic complexity of a strongly connected graph:&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;V(G) = e - n + p&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;e is the number of edges&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;n is the number of nodes&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;p is the number of connected regions&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;As we can see the cyclomatic complexity for both the strongly and weakly connected graphs are equivalent. Here is a list of all 5 linearly independent paths in the graphs on the right.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Path 1: A, B, C, B, C, G&amp;nbsp;&lt;/div&gt;&lt;div&gt;Path 2: A, B, C, G&lt;/div&gt;&lt;div&gt;Path 3: A, B, E, F, F&lt;/div&gt;&lt;div&gt;Path 4: A, D, E, F, G&lt;/div&gt;&lt;div&gt;Path 5: A, D, F, G&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Computing Minimum Number of Test Cases&lt;/b&gt;&lt;br /&gt;
In order to calculate the minimum number of test cases needed to traverse all statements, branches, simple-paths or loops in a graph we&#39;ll need to use the prime decomposition theorem. It states that any graph can be decomposed into a unique prime representation. This is good news for us because it&#39;s basically going to give us some shorthand to account for complexities in our graphs. Once we&#39;ve found the prime decomposition of the graph we will use a slightly different method to calculate the minimum number of test cases based on our traversal objectives.&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: left;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVa7szJ6g6Dg-b8Lu8jwUzExjFUXY6QKb06fBxVIWfJO5jjRIYBALkBbbl-FsssaA4OT3dFvSsfrlR-mXTCUkdQ1dfeHxESaHMQ03737DlmuyKTyUbThPvrJglZE7Kqm_NdngMU8cuQS9/s1600/prime+decomposition+chart.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;168&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWVa7szJ6g6Dg-b8Lu8jwUzExjFUXY6QKb06fBxVIWfJO5jjRIYBALkBbbl-FsssaA4OT3dFvSsfrlR-mXTCUkdQ1dfeHxESaHMQ03737DlmuyKTyUbThPvrJglZE7Kqm_NdngMU8cuQS9/s320/prime+decomposition+chart.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Click to enlarge.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;How to Create a Prime Graph&lt;/b&gt;&lt;br /&gt;
The trick as I mentioned earlier is that we will be creating some short hand for the types of statement that we can encounter in programming which would alter the complexity of our graph. Here is legend that refers to the programming construct and the related shorthand notation.&lt;br /&gt;
&lt;br /&gt;
Perhaps one of the best ways to learn how to decompose a graph will be to learn from an example. On the left hand side of the diagram below you will notice the corresponding control flow graph, while on the right hand side you will find the associated prime decomposition.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCXYFCQx3kY0-6P_NvKJNJL6bHDsTVQsuCUu6mZSrPmC2jsSib9duFjenG9lcIezkDsb0PZjQOEIOQoEKL-zirzlQhXEFzwFOAb8-7Zfr5rCAPQ8s17TOLzVI9lmionZRZui5bjugl6wE/s1600/e2q1.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;375&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCXYFCQx3kY0-6P_NvKJNJL6bHDsTVQsuCUu6mZSrPmC2jsSib9duFjenG9lcIezkDsb0PZjQOEIOQoEKL-zirzlQhXEFzwFOAb8-7Zfr5rCAPQ8s17TOLzVI9lmionZRZui5bjugl6wE/s400/e2q1.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;So, after you&#39;ve decomposed your graph and have found it&#39;s prime representation you can move on to figuring out what the minimum number of test cases will be. Depending on the strength of the type of testing you choose you will assign different values to each prime in the graph. We will then take the maximum value of the primes and add 1 to if to determine the minimum number of test cases. So the formula is &lt;b&gt;m(F) = Max + 1&lt;/b&gt;, written quite informally here where the max is the highest value assumed by any prime in your decomposition graph according the charts below.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhseRotOs1NWYTvQqzHrda6YieUOG7XFqlhyphenhyphen5vCTMMyhHlhROPFq_ZoI4RIbf_g8kUUiVNC-66voGHSisU-DfPxn-iOiAfpkDsSuWJlmidyBtOxJ_r1RSVmDgjD_2LurGmAGthDG5u5kVas/s1600/minum+number+of+tests.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;176&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhseRotOs1NWYTvQqzHrda6YieUOG7XFqlhyphenhyphen5vCTMMyhHlhROPFq_ZoI4RIbf_g8kUUiVNC-66voGHSisU-DfPxn-iOiAfpkDsSuWJlmidyBtOxJ_r1RSVmDgjD_2LurGmAGthDG5u5kVas/s400/minum+number+of+tests.gif&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dataflow Testing&lt;/b&gt;&lt;br /&gt;
This is a form of structural testing that focuses on the points at which variables are assigned values as well as the points at which those variables are referenced. This is in contrast to DD-Paths testing where we focus on the control flow of the program instead of the variable assignments. The types of errors that become most visible in dataflow testing are known as define/reference anomalies:&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- A variable that has been defined but never used (referenced)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- A variable that is used before it has been defined&lt;br /&gt;
&amp;nbsp;&amp;nbsp;- A variable that has been defined twice before it has been used&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Define/Use Testing&lt;/b&gt;&lt;br /&gt;
Define/Use testing focuses on the lifetime of a variable throughout your program. We construct a program graph in a similar way as we defined earlier only this time the nodes of the graph represent events associated with variables only. The events associated with variables are broken down into two categories, definitions and uses, hence the title.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Definitions&lt;/b&gt;&lt;br /&gt;
DEF(v, n)&amp;nbsp;- variable&amp;nbsp;v&amp;nbsp;at node n&amp;nbsp;&lt;u&gt;has&lt;/u&gt;&amp;nbsp;changed in value&lt;br /&gt;
&lt;br /&gt;
Formal definition:&amp;nbsp;node n element of G(P), is a defining node for the variable v element of V, iif the variable v is defined at the statement fragment corresponding to node n.&amp;nbsp;The following is a list of statements which are all considered to be examples of defining nodes:&lt;br /&gt;
- Input statements&lt;br /&gt;
- Assignment statements&lt;br /&gt;
- Loop control statements&lt;br /&gt;
- Procedure calls&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Uses&lt;/b&gt;&lt;br /&gt;
USE(v, n)&amp;nbsp;&lt;b&gt;&amp;nbsp;&lt;/b&gt;-&amp;nbsp;variable v at node n&amp;nbsp;&lt;u&gt;has not&lt;/u&gt;&amp;nbsp;changed in value&lt;br /&gt;
&lt;br /&gt;
Formal definition: node n element of G(P), is a usage node of the variable v element of V, iif the variable v is used at the statement fragment corresponding to the node n. The following is a list of statements which are all considered to be examples of usage nodes:&lt;br /&gt;
- Output statements&lt;br /&gt;
- Assignment statements&lt;br /&gt;
- Conditional statements&lt;br /&gt;
- Loop control statements&lt;br /&gt;
- Procedure calls&lt;br /&gt;
&lt;br /&gt;
**The most important notion to remember about Define/Use testing is that the value of the variable changes when it is defined and does not when it is used.&lt;br /&gt;
&lt;br /&gt;
One last subtlety about def/use testing before we wrap things up.&lt;br /&gt;
&lt;br /&gt;
Usage nodes can be further decomposed into predicate uses and computational uses. A predicate use, denoted P-USE(v, n), is defined as the usage of a variable v at node n, such that the corresponding statement fragment is a predicate. A computational use, denoted C-USE(v, n), is defined as the usage of variable v at node n, such that the corresponding statement fragment is a computational use. Take note that the node n will have an&lt;u&gt; outdegree greater than or equal to 2 &lt;/u&gt;in the case of a&lt;u&gt; P-USE&lt;/u&gt;. In the case of a &lt;u&gt;C-USE&lt;/u&gt; the &lt;u&gt;outdegree&lt;/u&gt; of node n will &lt;u&gt;always&lt;/u&gt; be &lt;u&gt;equal to 1&lt;/u&gt;.&lt;br /&gt;
&lt;br /&gt;
Now that we know how to define a node as being either a DEF or USE we can now proceed to the formal definition of a definition-use path, denoted du-path.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Definition of a DU-Path&lt;/b&gt;&lt;br /&gt;
a du-path with respect to variable v element of V is a path in PATHS(P) such that there exists define and usage nodes, DEF(v, m) and USE(v, n) where m and n are the initial and final nodes of the path.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Definition of a DC-Path&lt;/b&gt;&lt;br /&gt;
a definition clear path, denoted dc-path, with respect to variable v element of V is a path in PATHS(P) such that DEF(v, m) and USE(v, n) are the initial and final nodes of the graph respectively, additionally no other definition node exists for variable v other than DEF(v, m). This formal definition is just saying that for a single variable, the dc-path only contains a single node at which the respective variable is defined.&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;What this all boils down to is a single piece of advice... du-paths which are not definition clear are potential points of error in your code.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Test Coverage Metrics for DU-Paths: Rapps &amp;amp; Weyuker Dataflow Metrics&lt;/b&gt;&lt;br /&gt;
Now that we have defined all of the flavors of du-paths we can come up with some metrics to gauge our test coverage. The five metrics we will use are: All-Defs, All-Uses, All-DU-Paths, All-P-Uses/Some-C-Uses and All-C-Uses/Some-P-Uses.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All-Defs&lt;/b&gt;&lt;br /&gt;
The set of paths T in program graph G(P) of program P satisfies the all-defs criteria iif for every variable v element of V, T contains definition-clear paths from every defining node of v to a use of v.&lt;br /&gt;
&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLDyvlLiqgB37gv2sTCLJa-fXCWf97sV7ysIPNBR3R7DZYESDg8nuz4xRsDhJW8HCmPPs75uOFTQsWPmZFRNIfxoI1OysgQsaPYuon3QBX7OsiAqzEAnPunhKtjrS3-qtENJC34LyrRNrd/s1600/rapps-weyuker+dataflow+coverage+metrics.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLDyvlLiqgB37gv2sTCLJa-fXCWf97sV7ysIPNBR3R7DZYESDg8nuz4xRsDhJW8HCmPPs75uOFTQsWPmZFRNIfxoI1OysgQsaPYuon3QBX7OsiAqzEAnPunhKtjrS3-qtENJC34LyrRNrd/s320/rapps-weyuker+dataflow+coverage+metrics.png&quot; width=&quot;303&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Rapps-Weyuker hierarchy of dataflow coverage metrics&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;b&gt;All-Uses&lt;/b&gt;&lt;br /&gt;
The set of paths T in program graph G(P) of program P satisfies the all-uses criteria iif for every variable v element of V, T contains definition clear paths from every defining node of v to a use of v, as well as to the successor node of each USE(v, n). This is the union of all C-USES and P-USES.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;All-DU-Paths&lt;/b&gt;&lt;br /&gt;
The set of paths T in program graph G(P) of program P satisfies the All-DU-Paths criteria iif for every variable v element of V, T contains definition clear paths from every defining node of v to every use of v, and to the successor node of each USE(v, n), and that these paths are either single-loop traversals or cycle free.&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt; &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;All-P-Uses/Some-C-Uses&lt;/b&gt;&lt;br /&gt;
The set of paths T in program graph G(P) of program P satisfies the&amp;nbsp;All-P-Uses/Some-C-Uses criteria iif for every variable v element of V, T contains definition clear paths from every defining node of v to every p-use of v, and if a definition of v has no p-uses, there is a definition clear path path to at least one C-use.&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;b&gt;All-C-Uses/Some-P-Uses&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
The set of paths T in a program graph G(P) of program P satisfies the&amp;nbsp;All-C-Uses/Some-P-Uses criteria iif for every variable v elements of V, T contains definition clear paths from every defining node of v to every c-use of v, and if a definition of v has no c-uses, there is a definition clear path to at least one p-use.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Slice-Based Testing&lt;/b&gt;&lt;br /&gt;
A program slice is a set of program statements that contribute to the to the value of a for a variable at some point in the program. This perspective allows us to observe the behavior of a certain variable in isolation.&lt;br /&gt;
&lt;br /&gt;
Formal definition: A slice S on the variable set V at statement n, denoted S(V, n), is the set of all program statements prior to node n that contribute to the values of variables in V at node n. Note that listing all of the program statements which contribute to the values of the variables in V can be a lot of work. To speed things up it is recommended to list the node numbers in the path which affect the values of the set of variables in V. This means that USE nodes are not included in the set, only DEF nodes are.&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 15px;&quot;&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;White-Box Testing Strategies Strength Ranking:&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;font-weight: normal; margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;i&gt;*Note, the more +&#39;s the more strength&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;+ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;statement coverage&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;++ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;decision coverage&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;+++ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;condition coverage&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;++++ &amp;nbsp; &amp;nbsp; &amp;nbsp;condition decision coverage&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;+++++ &amp;nbsp; &amp;nbsp;multiple condition coverage&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0in;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;++++++ &amp;nbsp;path coverage (implicitly provides branch coverage)&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Integration Testing&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; text-align: right;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8t9cdg_TOCQNGPjh2wvsZGf05A0VOYBL36-TV8Ooczza-9C0ZGkEvkT8XMNTgBB-mjIP9pCFTlqTdg1qHI-VJAFQS9327B80SDLabqaDiALEh4rRIrTHONLqpd08EXyBrRY0VkZk6ljT2/s1600/call+graph.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;217&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8t9cdg_TOCQNGPjh2wvsZGf05A0VOYBL36-TV8Ooczza-9C0ZGkEvkT8XMNTgBB-mjIP9pCFTlqTdg1qHI-VJAFQS9327B80SDLabqaDiALEh4rRIrTHONLqpd08EXyBrRY0VkZk6ljT2/s320/call+graph.jpeg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Functional Decomposition Tree&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;Decomposition-Based Integration&lt;/b&gt;&lt;br /&gt;
Integration testing occurs once all of the unit testing has been completed. In fact, it presupposes that all of the code has already been broken down into functional units and that independently each performs as expected. The goal of integration testing is to combine multiple code units into coherent workflows and test the interactions between the various components. With this in mind I&#39;ll introduce the concept of the functional decomposition tree. The functional decomposition tree is the basis for integration testing as it represents the structural relationship of the system with respect to it&#39;s components. The way to construct the functional decomposition tree is to create nodes with directed edges, where the nodes represent modules or units and the edges represent the relationships or calls between these units. There are three main methods that can be used to traverse the tree: top-down, bottom-up, sandwich and the big-bang.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Functional Decomposition-Based Integration Methods&lt;/u&gt;&lt;br /&gt;
&lt;b&gt;Top-Down Integration&lt;/b&gt;&lt;br /&gt;
Traverse the tree from the top-down using a breadth-first approach, placing stubs where lower level units would normally be called. Stubs are throw away code fragments representing simulations of lower level units.The trick with the top-down approach is to gradually replace stubs with functional code. Suppose you have a unit with an outdegree of 5 and you replaced all of the stubs simultaneously, you could be creating a &quot;small-bang&quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Bottom-Up Integration&lt;/b&gt;&lt;br /&gt;
Traverse the tree from the bottom-up using drivers to simulate higher level modules making calls the lower levels. This is exactly the same thing we&#39;ve done in top-down integration only now we&#39;re approaching the graph from the bottom up. The only difference here is that we use drivers instead of stubs. Drivers are throw away bits of code as well but in practice it has been shown that drivers require less effort to create than stubs. Additionally due to the fan-out nature of most code, less drivers will be required to be written, albeit they will likely grow in complexity which in itself is a caveat.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sandwich Integration&lt;/b&gt;&lt;br /&gt;
This is a hybrid of the top-down and bottom-up methods where the tree is traversed simultaneously from both directions. This will result in you doing a big-bang on the various sub-trees, think of it as a depth-first approach to traversing the tree. The advantage here is that less drivers and stubs will be needed, however this convenience comes&amp;nbsp;at the expense of reduced fault isolation.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Big-Bang&lt;/b&gt;&lt;br /&gt;
In this method you simply test the code as one giant unit. This method requires the least effort although it also offers the least visibility for fault isolation.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Formula to calculate the number of integration tests needed:&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;Sessions = nodes - leaves + edges&lt;/div&gt;- For &lt;b&gt;top-down&lt;/b&gt; integration, &amp;nbsp;&lt;b&gt;nodes - 1 stubs&lt;/b&gt; are needed&lt;br /&gt;
- For &lt;b&gt;bottom-up&lt;/b&gt; integration, &lt;b&gt;nodes - leaves&lt;/b&gt; drivers are needed&lt;br /&gt;
&lt;i&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;*Note, a session is one set of tests for a specific configuration of code and stubs.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Call Graph Based Integration&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;Pairwise Integration&lt;/u&gt;&lt;br /&gt;
The goal of pairwise integration is to eliminate the need to develop stubs and drivers. Instead of using these throw away bits of code we resort to using the actual code in a more controller manner. We restrict a session to a pair of units in the call graph. The result of this restriction is that every edge on the call graph forms the basis for a test case. Thus the number of edges in the graph represents the number of test cases needed. The savings here is not in the number of test cases needed, as compared to the aforementioned decomposition-based integration methods, but rather in the reduced effort related to driver and stub development.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;Neighborhood Integration&lt;/u&gt;&lt;br /&gt;
By taking pairwise integration one step further we arrive at neighborhood integration. This method borrows the notion of a neighbor from topology theory, where a neighbor is defined as a node separated from the node of interest by a certain radius, normally 1. Thus all of the nodes one away from the node of interest, immediate predecessors and successors, are deemed to be within the neighborhood. The advantage of using this method is that the number of sessions can be greatly reduced, as compared to pairwise integration. Additionally there is a reduction in the number of drivers and stubs needed but we&#39;re essentially forming sandwiches, which as we saw have their own problems. To compute the number of neighborhoods on a call graph we use the following formula:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Neighborhoods = interior nodes + source nodes&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;This formula &amp;nbsp;can also be rewritten as&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;Neighborhoods = nodes - sink nodes&lt;/b&gt;&lt;br /&gt;
&lt;i&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: x-small;&quot;&gt;*Note, interior nodes have an indegree and outdegree &amp;gt;= 1, and source nodes are the roots of the tree.&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
The advantage of employing call graph based integration methods over functional decomposition trees is that we are moving away from a purely structural basis to a behavioral basis. These techniques also reduce the need for driver and stub development. The largest issue with graph-based integration is that fault isolation is reduced since we are dealing with compounded units of code. This can be especially troublesome when multiple units (nodes) all converge to a common node. Errors introduced at that point will likely require some code modifications in order to better isolate the fault, and re-testing of previously tested components becomes necessary.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Path-Based Integration&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;MM-Path&lt;/u&gt;&lt;br /&gt;
The idea behind path based integration is to trace a path through the source code as it executes resulting in a graph similar to a DD-Graph although this time we don&#39;t use decisions as a means to trace the control flow but rather use the invocations of units as edges on the graph. Notice again how we assume that the unit testing has been completed before moving on to this level of testing. MM-Paths are a hybrid of structural and functional testing, with the greatest advantage being that path based testing is closely related to system behavior. &amp;nbsp;Thus in order for us to construct an MM-Path we&#39;ll use the following definitions to guide us.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Source Node&lt;/b&gt;&lt;br /&gt;
A source node in a program is a statement fragment at which program executions begins or resumes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sink Node&lt;/b&gt;&lt;br /&gt;
A sink node is a statement fragment at which program execution terminates, or at which control is passed to another unit.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Module Execution Path&lt;/b&gt;&lt;br /&gt;
A module execution path is a sequence of statements that begins with a source node and ends with a sink node, without any intervening sink nodes (remember integration testing is presumed to be compete).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Message&lt;/b&gt;&lt;br /&gt;
A message is a mechanism by which one unit transfers control to another unit. Examples of messages are: method invocations, procedure calls and function references.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;MM-Path&lt;/b&gt;&lt;br /&gt;
An MM-Path is a sequence of module execution paths and messages.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;i&gt;&quot;A program path is a sequence of DD-Paths while a MM-Paths are a sequence of module execution paths.&quot;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;Guidelines for Determining the Length of an MM-Path&lt;/b&gt;&lt;br /&gt;
Two main indicators should be used to restrict the length of an MM-Path. The first is message quiescence and the second is data quiescence. Message quiescence occurs when a unit that doesn&#39;t send any messages is reached. Data quiescence occurs when a a sequence of processing culminates in the creation of data that is not immediately used.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Analyzing the Complexity of an MM-Path&lt;/b&gt;&lt;br /&gt;
The way to analyze the complexity of an MM-Path is to calculate it&#39;s cyclomatic complexity. Recall V(G) = e - n + 2p, but in this case p is always equal to 1.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;System Testing&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;hr /&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;The focus of this type of testing is at a very high level, in contrast to functional and structural testing.&amp;nbsp;The goal of system testing is to verify whether or not the system is doing what it is supposed to be doing. The basis from which a functional test is derived is a behavioral or functional specification. &amp;nbsp;In order to determine whether or not the system is behaving as expected, tests must be based upon workflows, use cases, etc... Notice how we are drawing inspiration from elements which lie at the boundary of the system. The basic construct that is used to build system tests is a thread. In the simplest terms a thread encapsulates the idea of one user level system goal. There is some controversy over the exact description of a thread and I&#39;ll do my best to describe it in an intuitive way, based on what we already know about testing. Unit testing tests individual functions, while integration testing focuses on interactions between units and system testing examines interactions among atomic system functions.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;Atomic System Function (ASF)&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;An atomic system function is a unit of code, which should have undergone unit testing by the time you&#39;ve gotten to system testing. ASF&#39;s are the building blocks from which system tests are derived. Unit level ASF&#39;s are the components which are used to construct DD-Paths with, while integration level ASF&#39;s are used to construct MM-Paths. Continuing along this trend we can restate our definition of a thread as a series of MM-Paths. Generally, an ASF is an action that is observed at the system level in terms of port input and output events (system boundaries).&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;b&gt;The Basic Concepts Used for Requirements Specifications&lt;/b&gt;&lt;br /&gt;
Since we now know that structural testing is based on verifying whether or not the system has met the user&#39;s requirements, a natural place to turn for testing inspiration is the requirements. It can often be difficult to determine how all the moving pieces inside the software system are supposed to interact and that is where some good design and architecture documents provide value. The requirements for a system can generally be broken down into the following five views: Data, &amp;nbsp;Actions, Devices, Events, Threads.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Data&lt;/u&gt;&lt;br /&gt;
When analyzing the data associated with a system attention is paid to how the data will be used, created and manipulated. A typical way of modeling the data view of a system is using an Entity/Relationship &amp;nbsp;diagram. The focus of the E/R model is to label data structures and provide insights on the data&#39;s relationship with other entities.&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;Actions&lt;/u&gt;&lt;br /&gt;
Action based modeling is still used commonly today, although it was even more popular when imperative programming was the &quot;new kid on the block&quot;. Actions have inputs and outputs represented by either data or port events. The I/O view of actions is the basis of functional testing while the decomposition of actions is the basis for structural testing. Actions are analogous to functions, methods, calls, processes, tasks, etc...&lt;/div&gt;&lt;br /&gt;
&lt;u&gt;Devices&lt;/u&gt;&lt;br /&gt;
Computer systems have a variety of ports used by external devices for communication. Although a port usually reminds us of a plugging in some external device, we can abstract this notion a step further by considering a port simply as a vehicle for input and output. This abstraction is useful in testing because it allows us to draw the focus away from the port devices and closer towards the logical relationship the ports have with the system.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Events&lt;/u&gt;&lt;br /&gt;
An event can be thought of as the translation of a physical event to a logical event occurring on a port device. A keystroke is an example of an event, as is updating a display. That being said we can see that an event has both data and action like properties.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;u&gt;Threads&lt;/u&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;A typical use of the system, in software terms, can be described as a &amp;nbsp;thread. A thread is a sequence of source instructions executed in conjunction with the servicing of a user&#39;s goal. Typically, a thread will be composed of calls to multiple classes or interfaces (MM-Paths). A thread is the highest level construct used in integration testing, but the smallest construct considered in system testing. One of the best ways to represent a thread is by using a finite state machine.&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;b&gt;Thread Testing&lt;/b&gt;&lt;br /&gt;
The way to go about testing threads isn&#39;t revolutionary, although it does require some thought. We will use port input and output events as the road map for creating graphs, which will be conjunctions of finite state machine representing threads. In this view, should we find it necessary test any particular thread more carefully, we would basically be conducting integration testing. Going even further we could then resort to unit testing to get to the root of any bug. We will encounter the issues with system testing graphs as we did with unit and integration testing in regards to path explosion. This forces us to choose our test paths wisely by taking advantage of the knowledge the directed graphs provide us with.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Finding Threads&lt;/b&gt;&lt;br /&gt;
The general strategy for finding threads is by tracing input and output events on a system level finite state machine. As we mentioned previously, a use-case or some other high level sequence of interactions with system are used to create the context for the state machine. It is recommended to create the state machine such that transitions correspond to port input events, while port output events are represented by actions on transitions.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Structural Strategies for Thread Testing&lt;/b&gt;&lt;br /&gt;
Since we are using directed graphs to represent the interactions of threads we can reuse the same test coverage metrics we discovered in unit testing, namely node and edge coverage. Node coverage at the system level is equivalent to statement coverage at the unit level. Node coverage is the minimum a tester can do, although the recommended approach is to use edge coverage. Edge coverage at the system level has the added benefit of guaranteeing port event coverage as well.&lt;br /&gt;
&lt;br /&gt;
System testing becomes a little bit more complicated when we don&#39;t have a behavioral model for the system to be tested. This will require us to find inspiration within three of the aforementioned basis concepts: ports, events and data.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Event-Based Thread Testing&lt;/b&gt;&lt;br /&gt;
We begin thinking about event based thread testing by considering port input events. Within the realm of port input events the following five coverage metrics are introduced:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;PI1:&lt;/b&gt; Each port input event occurs&lt;br /&gt;
&lt;b&gt;PI2:&lt;/b&gt; Common sequences of port input events occur&lt;br /&gt;
&lt;b&gt;PI3:&lt;/b&gt; Each port input event occurs in every relevant data context&lt;br /&gt;
&lt;b&gt;PI4:&lt;/b&gt; For a given context, all inappropriate input events occur&lt;br /&gt;
&lt;b&gt;PI5:&lt;/b&gt; For&amp;nbsp;a given context, all possible input events occur&lt;br /&gt;
&lt;br /&gt;
The PI1 metric is regarded as the bare minimum and is often inadequate for proper testing.&lt;br /&gt;
&lt;br /&gt;
PI2 coverage is the most common because it emanates from the most intuitive view, the normal use of the system. Within the scope of defining normal use of the system is may not necessarily be trivial to identify all commons sequences of port input events.&lt;br /&gt;
&lt;br /&gt;
PI3 coverage like PI4 and PI5 are context specific metrics. We will define a context as a point of event&amp;nbsp;quiescence. Event quiescence is the point at which some event terminates, an example of this is a screen popping up letting the user know the supplied username and password combination is invalid. These points in an event driven system will normally correspond to responses provided by the system to user requests (which are also events).&lt;br /&gt;
&lt;br /&gt;
So getting back to the definition of PI3 coverage, the focus in this scenario is on developing test cases that are based on events that have logical meanings determined by the context in which they occur. Consider an example at an ATM machine, where the buttons on the sides of the screens take on different actions depending on what point in the transaction sequence you are at. The thing to remember about PI3 coverage is that is driven by an event within each context.&lt;br /&gt;
&lt;br /&gt;
PI4 and PI5 coverages are opposite of one another. The both start with a context though and seek to describe relevant events. PI4 begins with a context and seeks to wreak havoc on the system by supplying strictly invalid inputs, while PI5 attempts to only provide valid inputs. The PI4 metric is normally used on more of a casual hacking basis, so as to uncover weaknesses in the system. PI4 and PI5 are both effective methods at testing a system although some interesting questions arise when we begin to think about breaking the system. A Venn diagram could really help out here, let&#39;s imagine one. The circle on the left represents all of the inputs a system is designed to handle. The circle on the right contains every other possible input which has not been defined in the system specification. The union of the two circles represents the inputs which have been specified by the system that are invalid. Now the question is, how do we quantify what the remainder of invalid inputs that exist in the circle on the right? That is challenge in testing with PI4. PI5 testing is much more straight-forward since the requirements should provide all of the information needed to determine what the valid inputs exist.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Port Coverage Metrics&lt;/b&gt;&lt;br /&gt;
&amp;nbsp;Another metric that can be used to gauge the graph coverage is port coverage:&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;PO1: &lt;/b&gt;Each port output event occurs&lt;br /&gt;
&lt;b&gt;PO2:&lt;/b&gt; Each port output event occurs for each cause&lt;br /&gt;
&lt;br /&gt;
PO1 coverage is acceptable minimum and is extremely useful when a system has a large variety of output messages when errors occur. PO2 coverage is a worthy goal however it can sometime be difficult to quantify. PO2 coverage focuses on threads that interact in response to a port output event, note that output events are usually caused by very few inputs.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Port-Based Thread Testing&lt;/b&gt;&lt;br /&gt;
Port-based thread testing is useful when used in conjunction with event based testing. The strategy here is to determine which events can occur at each port. Once the list has been compiled we seek threads that will test each possible event at a port with port input and output. Event-based testing exposes the many to one relationship between events and ports. Port-based testing looks at the relationship from the opposite perspective, identifying the many to one relationship between ports and events. This type of testing is especially useful for systems when third party suppliers provide port devices.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Data-Based Thread Testing&lt;/b&gt;&lt;br /&gt;
Systems that are event based are not good candidates for data-based testing, usually. Data driven systems on the other hand oddly enough lend themselves well to data-based thread testing. Since data based system will often have requirements stipulated in terms of the modification of some data, these actions form a natural basis to identify threads. For example, suppose we were looking at a system designed to keep track of video rentals. Much of the systems functionality would be prescribed in terms of data transactions, like create client accounts, rent movies, return movies, etc... The best way to analyze the data of a system is to look at the E/R diagrams. The relationships in the E/R diagrams are particularly useful to notice since system level threads are usually the ones responsible for populating the relevant data for each entity. At the system level it is more likely that we would encounter threads which are responsible for maintaining data for a single entity.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DM1: &lt;/b&gt;Exercise the cardinality of each relationship&lt;br /&gt;
&lt;b&gt;DM2:&lt;/b&gt;&amp;nbsp;Exercise the participation of every relationship&lt;br /&gt;
&lt;b&gt;DM3:&lt;/b&gt; Exercise the functional dependencies among relationships&lt;br /&gt;
&lt;br /&gt;
The cardinality of a relationship refers to the following four types of relationships: one-to-one, one-to-many, many-to-one and many-to-many. Each one of these possibilities can be seen as a thread from a testing perspective.&lt;br /&gt;
&lt;br /&gt;
Participation relates to the the level of participation of each entity within a relationship. For instance, in a many-to-many scenario each entity would need to be observed to ensure that it properly fulfilled it&#39;s relationship specifications. These points of observation could easily be turned into system level testing threads.&lt;br /&gt;
&lt;br /&gt;
Functional dependencies are stringent logical relationship constrains that are placed upon entities. These dependencies naturally become converted to threads which are testable.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Operational Profiles&lt;/b&gt;&lt;br /&gt;
Zipf&#39;s law states that 80% of a systems activity occurs within 20% of the space. This law manifests itself in software as the principle of locality of reference. The implication of this law on testing is that some threads will be traversed more often than others. Thus if we were to evaluate the reliability of the system, failures which occur in popular threads would cause the majority of the problems. The intuition here is that we if we focus on testing threads that occur more often we could potentially increase the reliability of the system immensely. Less tested threads which still may contain faults produce less errors overall since those threads are not executed as often. An operational profile is the concept of determining the execution frequencies of various threads, and then using this information in deciding which threads to test. One of the best ways to keep tabs on which threads occur most often is to assign weights to edges in the finite state machines representing how often that edge will be traversed. Using this method it is easy to determine what the probability that a given thread will be executed, simply multiply all of the probabilities along the way.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Progression Testing Versus Regression Testing&lt;/b&gt;&lt;br /&gt;
Regression testing is used to verify that any new functionality that has been added to a system has not compromised any previously functioning components from earlier builds. As the number of builds increases, the number of tests re-run on previously built components becomes non-trivial. Progression testing is that act of conducting tests on newly built components. Naturally we expect the number of failures to be much higher for the progression tests than the regression tests. So in order to be certain that the newly written code is bug free we must devise a plan that will allow us to easily isolate faults in the code. The best way to do this is create small threads for starters that can only fail in a few ways. After we have sufficiently tested a small thread we can integrate it into a larger thread, thus furthering our testing. We would use the opposite strategy for regression testing, having longer threads with more potential sources of error since we are less concerned with fault isolation in regression tests. As a general rule of thumb we can say that &quot;good&quot; regression testing utilizes threads with low operational frequency while progression testing threads should focus on high operational frequency threads.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Software Reliability Engineering (SRE)&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;&lt;b&gt;Classical Definition of Reliability&lt;/b&gt;&lt;br /&gt;
Software reliability is the probability that a system will operate without failure under given environmental conditions for a specified period of time.&amp;nbsp;Reliability is measured over execution time so that it more accurately reflects system usage.&amp;nbsp;Software Reliability goes hand-in-hand with software verification.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Essential Components of Software Reliability Engineering&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Establish reliability goals&lt;/li&gt;
&lt;li&gt;Develop operational profile&lt;/li&gt;
&lt;li&gt;Plan and execute tests&lt;/li&gt;
&lt;li&gt;Use test results to drive decisions&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Approaches to Achieve Reliable Software Systems&lt;/b&gt;&lt;br /&gt;
&lt;u&gt;Fault Prevention&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;&lt;/u&gt;To avoid, by construction, fault occurrences.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Fault Removal&lt;/u&gt;&lt;br /&gt;
To detect, by verification and validation, the existence of faults and eliminate them.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Fault Tolerance&lt;/u&gt;&lt;br /&gt;
To provide, by redundancy, service complying with the specification in spite of faults having occurred or occurring.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Fail/Failure Forecasting&lt;/u&gt;&lt;br /&gt;
To estimate, by evaluation, the presence of faults and the occurrence and consequences of failures.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;font-weight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;&lt;b&gt;Software Reliability Models&lt;/b&gt;&lt;/b&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Time-dependent&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;ul style=&quot;font-weight: normal;&quot;&gt;&lt;li&gt;&lt;b&gt;Time between failures&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Failure count&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div style=&quot;font-weight: normal;&quot;&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Time-independent&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;ul style=&quot;font-weight: normal;&quot;&gt;&lt;li&gt;&lt;b&gt;Fault seeding&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Equivalence classes&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;b&gt;Time-dependent Reliability Models&lt;/b&gt;&lt;br /&gt;
Reliability Measures: MTTF, MTTR, MTBF&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;Mean Time To Failure (MTTF)&lt;/u&gt;&lt;br /&gt;
Total operating time dicided by the total nmber of faulures encountered (assuming the failure rate is constant)&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Mean Time To Repair (MTTR)&lt;/u&gt;&lt;br /&gt;
Software component&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;Mean Time Between Failures&lt;/u&gt;&lt;br /&gt;
MTBF = MTTR + MTTF&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Reliability Growth Models&lt;/u&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Basic Exponential model &amp;nbsp; &amp;nbsp; - Assumes finite number of failures over infinite amount of time&lt;/li&gt;
&lt;li&gt;Logarithmic Poisson model - Assumes infinite number of failures&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Parameters involved in reliability growth models:&lt;br /&gt;
1)&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;DejaVu Sans&#39;, sans-serif; line-height: 16px;&quot;&gt;λ &lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;= Failure intensity, i.e. how often failures occur per time unit.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;2)&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;DejaVu Sans&#39;, sans-serif; font-size: 17px;&quot;&gt;τ&lt;/span&gt;&amp;nbsp;= &amp;nbsp;Execution time, i.e. how long the program has been running.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;3)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: serif; line-height: 17px;&quot;&gt;μ = Mean failures experienced within a time interval.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Jelinski-Moranda Model&lt;/u&gt;&lt;br /&gt;
Assumptions:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;The software has N&lt;sub&gt;0&amp;nbsp;&lt;/sub&gt;faults at the beginning of the test&lt;/li&gt;
&lt;li&gt;Each of the faults is independent and all faults will cause a failure during testing&lt;/li&gt;
&lt;li&gt;The repair process is instantaneous and perfect, i.e., the time to remove the fault is negligible, new faults will not be introduced during fault removal.&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Time-independent Reliability Models&lt;/b&gt;&lt;/div&gt;&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;Fault Seeding (Injection)&lt;/u&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;The definition of fault seeding is as follows. Fault seeding is the process of intentionally adding errors into a software program for the purpose of estimating the number of faults that are already contained within the system. What the definition doesn&#39;t tell you is how you can estimate how many faults still exist in the program. The number of faults estimated to be remaining in the system is a function of the programmers ability to discover the faults which have been intentionally introduced.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;Let A represent the number of faults intentionally introduced&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;Let f be the number of failures that have occurred as a result of executing the flawed code&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;Let i be the number of failures which did not emanate from the newly introduced faults (All failures - f)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;Finally let N - i represent the estimated number of faults remaining in the code&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;N / i = A / f, rearranging to solve for N we have N = A / (f * i)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;finally we calculate N - i to get the estimated number of remaining faults in the system&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;u&gt;Equivalence Classes&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;In order to derive an equivalence class in system testing you must create an operational profile for each thread. Once this profile has been created you should have a weight that refers to the likelihood that thread would be called during the execution life-cycle. Each path through the operational profile provides you with an equivalence class. Each path has a certain probability of execution which is obtained by multiplying the probabilities of each thread in the path. &lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;&quot;&gt;&lt;b&gt;&lt;u&gt;Software Versus Hardware Reliability&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt; &lt;th&gt;Software Reliability&lt;/th&gt; &lt;th&gt;Hardware Reliability&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Failures are primarily due to design faults. Repairs are made by modifying the design to make it robust against conditions that can trigger a failure.&lt;/td&gt; &lt;td&gt;Failures are caused by deficiencies in design, production and maintenance.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;The is no wear-out phenomena. Software Errors occur without warning. “Old” code can exhibit an increasing failure rate as a function of errors induced while making upgrades.&lt;/td&gt; &lt;td&gt;Failures are due to wear or other energy-related phenomena. Sometimes a warning is available before a failure occurs.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;There is no equivalent preventive maintenance for software.&lt;/td&gt; &lt;td&gt;Repairs can be made which would make the equipment more reliable through maintenance.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Reliability is not time dependent. Failures can occur when the logic path that contains an error is executed. Reliability growth is observed as errors are detected and corrected.&lt;/td&gt; &lt;td&gt;Reliability is time related. Failure rates can be decreasing, constant or increasing with respect to operating time.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;External environment conditions do not affect software reliability. Internal environment conditions, such as insufficient memory or inappropriate clock speeds do affect software reliability.&lt;/td&gt; &lt;td&gt;Reliability is related to environmental conditions.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Reliability cannot be improved by redundancy, since this will simply replicate the same error. Reliability can be improved by diversity.&lt;/td&gt; &lt;td&gt;Reliability can usually be improved by redundancy.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Failure rates of software components are not predictable.&lt;/td&gt; &lt;td&gt;Failure rates of components are somewhat predictable according to known patterns.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Software interfaces are conceptual.&lt;/td&gt; &lt;td&gt;Hardware interfaces are visual.&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;Software design does not use standard components.&lt;/td&gt; &lt;td&gt;Hardware design uses standard components.&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Model Checking and Formal Verification&lt;/b&gt;&lt;br /&gt;
&lt;hr /&gt;Any verification using model-based techniques is only as good as the model of the system. As all other engineers must be embrace mathematics, software engineers should embrace formal methods.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;b&gt;Model Verification&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;table border=&quot;1&quot; style=&quot;text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Input&lt;/th&gt;&lt;th&gt;Output&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;formal model + property&lt;/td&gt;&lt;td&gt;Model Checking: True ; Counter Example&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-weight: bold;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-weight: bold;&quot;&gt;Testing Versus Model Checking&lt;/span&gt;&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Testing&lt;/th&gt;&lt;th&gt;Formal Methods&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Informal specification&lt;/td&gt;&lt;td&gt;Work on a model of the program&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Cannot exhaustively test the system&lt;/td&gt;&lt;td&gt;Targets concurrent systems&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Widely used technique in practice&lt;/td&gt;&lt;td&gt;Successful in hardware systems and communications protocols&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Temporal Logic&lt;/b&gt;&lt;br /&gt;
The formulas can express fact about past, present and future states.&lt;br /&gt;
&lt;u&gt;&lt;br /&gt;
&lt;/u&gt;&lt;br /&gt;
&lt;u&gt;Classification of Temporal Properties&lt;/u&gt;&lt;br /&gt;
&lt;b&gt;1) Safety:&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;properties state that nothing bad can happen&lt;br /&gt;
&lt;b&gt;2) Liveness:&lt;/b&gt;&amp;nbsp;properties state that something good will eventually happen&lt;br /&gt;
&lt;b&gt;3) Fairness:&lt;/b&gt;&amp;nbsp;properties state that every request is eventually granted&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;More to come soon....&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Excellent Book on the topic:&lt;/b&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #007000; font-family: monospace; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 16px;&quot;&gt;&lt;a href=&quot;http://www.amazon.com/Software-Testing-Craftsmans-Approach-Third/dp/0849374758?ie=UTF8&amp;amp;tag=widgetsamazon-20&amp;amp;link_code=bil&amp;amp;camp=213689&amp;amp;creative=392969&quot; imageanchor=&quot;1&quot; target=&quot;_blank&quot;&gt;&lt;img alt=&quot;Software Testing: A Craftsman&#39;s Approach, Third Edition&quot; src=&quot;http://ws.amazon.com/widgets/q?MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;ID=AsinImage&amp;amp;WS=1&amp;amp;Format=_SL160_&amp;amp;ASIN=0849374758&amp;amp;tag=widgetsamazon-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=widgetsamazon-20&amp;amp;l=bil&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=0849374758&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/5114482219816201850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/software-testing.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/5114482219816201850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/5114482219816201850'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/software-testing.html' title='Software Testing'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIGTxNXm6B9SGkkpn4fxKcACUpJo5ZlBa9jU2JA-lz3HoqFMte4DjaaJ_6rKMyVQtSW2IXoD3G8Qn70aUmum5HrQSoUW_ikL7OgIeJ1ljuX1YvHO1fl2_Dg6je1gEaemd2kF5EutlYT8Eu/s72-c/Software_Testing_Life_Cycle.gif" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-2903035542750253795</id><published>2011-01-03T21:48:00.007-05:00</published><updated>2011-04-10T17:20:39.098-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="command"/><title type='text'>Useful Bash Terminal Commands</title><content type='html'>This is a brief reference of some bash terminal commands to keep handy.&lt;br /&gt;
&lt;br /&gt;
Copy all files in a directory&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;user@pc:~$&amp;nbsp;cp -R /thisFolder&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Pause a process that is currently executing.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$&amp;nbsp;CTRL + z&lt;/pre&gt;&lt;br /&gt;
See a list of Jobs which have been paused&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ jobs&lt;/pre&gt;&lt;br /&gt;
Resume a process that has been paused&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ fg&lt;/pre&gt;&lt;br /&gt;
Stop of process that is currently executing&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ CTRL + c&lt;/pre&gt;&lt;br /&gt;
View the history of the previous commands that have been entered. Each previous command will be enumerated for convenient re-use.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ history&lt;/pre&gt;&lt;br /&gt;
To re-run a command from the command history take note of the command number associated with the command from running the history command. Alternately you can type CTRL + r and start typing a command, and a matching command will be looked up in the history.&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;user@pc:~$ !18&lt;/pre&gt;&lt;br /&gt;
Create a compressed archive file from the files foo and bar&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot; style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;user@pc:~$ tar -cf archive.tar foo bar&lt;/pre&gt;&lt;br /&gt;
Copy files over shh with the scp command to the current working directory&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;user@pc:~$ scp userName@yourServer:/path/to/files/you/want/ .&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;Add a new repository to your apt-get list, in this case the Mozilla stable repo&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;user@pc:~$ sudo add-apt-repository ppa:mozillateam/firefox-stable&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;div style=&quot;font-family: &#39;Times New Roman&#39;; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;Update your local repository listing&lt;/div&gt;&lt;div style=&quot;font-family: &#39;Times New Roman&#39;; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; white-space: normal;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre;&quot;&gt;user@pc:~$ sudo apt-get update&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
I know this list is quite short at the moment but I&#39;ll be adding to it as I have time. In the mean time if any of my reader would like to contribute and comments I&#39;ll be sure to update my post accordingly.</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/2903035542750253795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/useful-bash-terminal-commands.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/2903035542750253795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/2903035542750253795'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/useful-bash-terminal-commands.html' title='Useful Bash Terminal Commands'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-8408033002404278671</id><published>2011-01-03T21:30:00.005-05:00</published><updated>2011-01-03T21:39:59.311-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="operators"/><category scheme="http://www.blogger.com/atom/ns#" term="Perl"/><title type='text'>Perl - Logical Operators</title><content type='html'>This is a concise tutorial on logical operators in Perl.&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;Logical Operators Quick Reference Table&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;th&gt;&lt;b&gt;Logical Meaning&lt;/b&gt;&lt;/th&gt; &lt;th&gt;&lt;b&gt;Perl Code&lt;/b&gt;&lt;/th&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;numeric equals&lt;/td&gt; &lt;td&gt;==&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;numeric not equals&lt;/td&gt; &lt;td&gt;!=&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;LHS greater than or equal to RHS&lt;/td&gt; &lt;td&gt;&amp;gt;=&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;LHS less than or equal to RHS&lt;/td&gt; &lt;td&gt;&amp;lt;=&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;and&lt;/td&gt; &lt;td&gt;&amp;amp;&amp;amp;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;or&lt;/td&gt; &lt;td&gt;||&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;string equals&lt;/td&gt; &lt;td&gt;eq&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td&gt;string not equals&lt;/td&gt; &lt;td&gt;ne&lt;/td&gt; &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
There will be more to come on this one but for the moment I&#39;ll just leave you with a link to the &lt;a href=&quot;http://perldoc.perl.org/perlop.html&quot;&gt;perl op docs&lt;/a&gt; which is a comprehensive resource.</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/8408033002404278671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/perl-logical-operators.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/8408033002404278671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/8408033002404278671'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2011/01/perl-logical-operators.html' title='Perl - Logical Operators'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4576395684360624786</id><published>2010-12-28T20:46:00.000-05:00</published><updated>2010-12-28T20:46:44.154-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="GET"/><category scheme="http://www.blogger.com/atom/ns#" term="Perl"/><category scheme="http://www.blogger.com/atom/ns#" term="scraping"/><title type='text'>Perl script to GET a web page</title><content type='html'>Recently I found it necessary to do a little web page scraping and concocted a little Perl script to help me get the job done. The script I&#39;ve provided below contains a single function that will get the contents of a web page whose URL is passed as the sole parameter to the function. I would likely embed this function within another script to make it easily accessible. I&#39;ve taken the time to place a lot of comments into the script itself so this post will be short and sweet. You&#39;ll need to have the &lt;a href=&quot;http://search.cpan.org/~crisb/WWW-Curl/Easy.pm.in&quot;&gt;CURL library&lt;/a&gt; installed in order for this script to work, and please make sure you are using the most recent version (at the time of writing this post it is 3.12).&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;
#!/usr/bin/perl

use strict;
use warnings;
use WWW::Curl::Easy;

# Script produced by Benjamin Crudo on December 28, 2010.
# Feel free to use it and learn from it without me suing you.

# Note this function expects a single parameter which should be in the form of a URL
# Here is an example of a valid call to this function:
# $web_page = &amp;getWebPage(&quot;http://www.google.com&quot;);

sub getWebPage 
{
  # Setting up the Curl parameters
  my $curl = WWW::Curl::Easy-&gt;new; # create a variable to store the curl object

  # A parameter set to 1 tells the library to include the header in the body output.
  # This is only relevant for protocols that actually have headers preceding the data (like HTTP).
  $curl-&gt;setopt(CURLOPT_HEADER, 1);

  # Setting the target URL to retrieve with the passed parameter
  $curl-&gt;setopt(CURLOPT_URL, @_);

  # Declaring a variable to store the response from the Curl request
  my $response_body = &#39;&#39;;

  # Creating a file handle for CURL to output to, then redirecting our output to the $response_body variable
  open(my $fileb, &quot;&gt;&quot;,\$response_body) or die $!;
  $curl-&gt;setopt(CURLOPT_WRITEDATA, $fileb);

  # getting the return code from the header to see if the GET was successful
  my $return_code = $curl-&gt;perform;

  # capturing the response code from the GET request in the HTTP header, i.e... 200, 404, 500, etc...
  # 200 is success
  my $response_code = $curl-&gt;getinfo(CURLINFO_HTTP_CODE);  

  # if the return code is zero than the request was a success
  if ($return_code == 0)
  {    
    # A little debug output to keep you informed
    print (&quot;Success &quot;. $response_code.&quot;: &quot;.@_.&quot;\n&quot;);

    # return whatever was contained on the web page that we just got using a GET
    return $response_body;
  }

  else
  {
    print (&quot;Failure &quot;. $response_code.&quot;: &quot;.@_.&quot;\n&quot;);
  }

  close($fileb); # close the file-handle
}


&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4576395684360624786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2010/12/perl-script-to-get-web-page.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4576395684360624786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4576395684360624786'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2010/12/perl-script-to-get-web-page.html' title='Perl script to GET a web page'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7763195273365582447.post-4573857506531326214</id><published>2010-12-27T00:47:00.054-05:00</published><updated>2010-12-27T21:20:44.556-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JDBC"/><category scheme="http://www.blogger.com/atom/ns#" term="LAMP"/><category scheme="http://www.blogger.com/atom/ns#" term="MySQL"/><category scheme="http://www.blogger.com/atom/ns#" term="SQL"/><title type='text'>MySQL Reference Book</title><content type='html'>Before you begin reading my code please take note of the following conventions.&lt;br /&gt;
Wherever I expect you to replace my generic code with your own specific code I have placed square brackets around the term, such as this [&lt;i&gt;replaceMe&lt;/i&gt;]. Also please note that it is conventional to place SQL commands in upper-case letters to distinguish those terms from your input.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;Ubuntu Commands:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;Start MySQL server: &lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;mysql -u [user_name] -p
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;
SQL Commands:&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Show all databases on server: &lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;SHOW DATABASES;
&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
Delete a database:&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot;&gt;DROP DATABASE [database_name];
&lt;/pre&gt;&lt;div&gt;Note this function will return the number of tables that were removed. This corresponds to the number of .frm files removed.&lt;/div&gt;&lt;br /&gt;
Select database for use: &lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;USE [database_name];
&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
Show tables in a database:&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot; style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;SHOW TABLES;
&lt;/pre&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;br /&gt;
Show a table&#39;s schema:&lt;/div&gt;&lt;div style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;&lt;/div&gt;&lt;pre class=&quot;brush: csharp&quot; style=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;&quot;&gt;DESCRIBE [table_name];
&lt;/pre&gt;&lt;br /&gt;
Add a column to an existing table:&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;ALTER TABLE [table_name] ADD COLUMN [column_name] varchar(255); 
&lt;/pre&gt;Note in this case the varchar(255) data type can be replaced by any valid SQL data type. Also further restrictions can be placed after the data type just like in a CREATE statement for foreign keys, NOT NULL, etc...&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;Java and MySQL&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
In order to connect your Java program to a MySQL database there are a couple of things you need to handle first. Obviously you need a MySQL database server to be running somewhere, locally or remotely. Next you will need the MySQL driver&amp;nbsp;&lt;i&gt;&lt;a href=&quot;http://dev.mysql.com/downloads/connector/j/&quot;&gt;mysql-connector-java-5.1.14-bin.jar&lt;/a&gt;&lt;/i&gt; file to be included in the class path of your Java project. Please take care that you don&#39;t skip the last step and you will never be able to achieve a connection to the database without the driver properly installed, and most unfortunately the compiler will not return any meaningful errors other than a connection to the database is not possible. Next you&#39;ll need some Java code which I provide below and a table in the database which you can query. Here is a sample program that connects to a database called taskManager and performs a query to return all of the data from the singleTask table.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: csharp&quot;&gt;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;


public class MysqlDriver {
 
 public static void main (String[] args) {
  MysqlDriver driver = new MysqlDriver();
 }
 
 private String db_path = &quot;localhost:3306&quot;;
 private String db_name = &quot;taskManager&quot;;
 private String db_user = &quot;root&quot;;
 private String db_pass = &quot;secret&quot;;
 private String db_url = &quot;jdbc:mysql://&quot;+db_path+&quot;/&quot;+db_name;
 
 public MysqlDriver() {
  
  try {
   Class.forName(&quot;com.mysql.jdbc.Driver&quot;);
   Connection db = DriverManager.getConnection(db_url, db_user, db_pass);
    System.out.println(&quot;Connected to the database&quot;);
   
   String statement = &quot;SELECT * FROM singleTask&quot;;
   PreparedStatement db_statement = db.prepareStatement(statement);
   ResultSet result_set = db_statement.executeQuery();
   
   while(result_set.next()) {
    String oid = result_set.getString(&quot;oid&quot;);
    String desc = result_set.getString(&quot;description&quot;);
    System.out.println(&quot;ObjectID: &quot;+oid+&quot;\tDescription: &quot;+desc);
   }
   
  }
  catch(Exception e) {
   System.out.println(&quot;We could not connect to the database located at: &quot; + db_path);
  }
 }
 
}

&lt;/pre&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: large;&quot;&gt;References:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;-&amp;nbsp;&lt;a href=&quot;https://help.ubuntu.com/community/ApacheMySQLPHP&quot;&gt;LAMP Setup on Ubuntu&lt;/a&gt;&lt;br /&gt;
-&amp;nbsp;&lt;a href=&quot;http://www.developer.com/article.php/3417381&quot;&gt;MySQL and JDBC&lt;/a&gt;&lt;br /&gt;
- &lt;a href=&quot;http://www.pantz.org/software/mysql/mysqlcommands.html&quot;&gt;MySQL Command Refernce&lt;/a&gt;&lt;br /&gt;
- &lt;a href=&quot;http://www.mckoi.com/database/SQLSyntax.html&quot;&gt;SQL Syntax Index&lt;/a&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://binaryengineering.blogspot.com/feeds/4573857506531326214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://binaryengineering.blogspot.com/2010/12/mysql-book.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4573857506531326214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7763195273365582447/posts/default/4573857506531326214'/><link rel='alternate' type='text/html' href='http://binaryengineering.blogspot.com/2010/12/mysql-book.html' title='MySQL Reference Book'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>