I am trying to understand how this software auto update might be working.
There could be three steps in it
1) Check for the availability of new version
2) Download the latest version
3) Install the downloaded version of software
Next i am going to expand on how each step could be designed or implemented
Check for availability of new version
When the current version of the application is started it could do the following in a background thread
1) Read the current version all the component that could be updated in the software
2) Go the vendor
software update web server and check for the availability of newer version
2.1) Only if the exiting software license supports free updates
3) If newers version ar available the goto step2 or do nothing
Download the latest version
Options
1) Update the software user about the availability of newer version by displaying a message box and request the user for a manual update
2) Update the software user about the availability of newer version by dispaying a message box and request the user to intiate the auto download
2.1) Perform the download in the background (HTTP or FTP)
If download is successfully completed then goto to step 3 or display the error message to the user and the user to try again later.
Install the downloaded version of software
Note: Technology should support installation of newer version when current version of the software is running.
Install the downloaded software and request the user to restart the software.
Not sure how much of the above understanding and ideas are correct?
Load balance your website.
1) Use DNS (Domain Name Server) to distribute your website load.
2) Use Load Balancing Switch to distribute your website load.
The above mentioned load balancing methods work very well for static websites. But if your website have to do back end processing with a database or any other service, then even those services have to be load balanced otherwise they would become the bottle neck.
The above stuff is just the beginning of the vast topic called "Scalability"!
Abstraction interface
1) System abstraction interface help in hiding the complexity of the actual system and also the changes with in the system transparent to users of the system like hardware upgrade or adding hardware resource to scale up....
Scalability on the client
1) Paging concept (showing only few mail subjects on a mail client)
Scalability on the web/app server
1) multiple threads to handle http request
2) Load balancing architecture (one load balancing proxy server with multiple app server) to handle http request
onConfigurationChanged - orientation change
Having "android:configChanges="orientation|keyboard" in manifest reloads the android activity on orientation change.
Instead the correct property is
addJavascriptInterface - webview & javascript
When passing argument from javascript to android, pass it as string. Now if you want to convert the passed string to Integer or Long, the do not use Integer.getInteger instead use Integer.valueOf, that is, use valueOf. Java Math.ceil with Integers
If your try to do some thing like
Integer a=1;
Integer b=5;
Integer c=0;
c=(int)Math.ceil(a/b);
You will get only 0;
Instead do something like
Integer a=1;
Integer b=5;
Integer c=0;
c=(int)Math.ceil((a * 1.0)/b);
So that you will get 1.
cursor.close() - Right place to close the sqlite cursor
Don't
Developing a website or web application which can be indexed by search engine is very critical and it is called searching engine optimization of the website or web application.
Before starting the optimization let us look at some of the basic rules to be followed
Rule: Focus on the originality and quality of the content of your website.
Rule: Remember your ultimate consumers are your users, not search engines.
Rule: Original content is ranked high in the search result page.
Rule: Increasing the traffic to your website is more important than the rank of the page in the search result.
Rule: Perform any kind of optimization only to improve the user experience.
Below are some of the critical optimization rules
Rule: Use brief, but descriptive title in "title" (<title>Search engine optimization<title/>) tag. Choose a title that effectively communicates the topic of the page's content.
Rule: Create unique title for each page of the website.
Rule: Google search engine does not use keywords "meta" tag (<meta name="keywords" content="search engine optimization, indexing, optimization, rules" />) for indexing.
Rule: Provide crisp and clear description of the webpage in the description "meta" tag (<meta name="description" content="Critical rules for search engine optimization." />). Also provide unique description for each page of the website.
Rule: Use | (pipe) or - (hyphen) as separator and not _ (underscore) in "title" tag and description "meta" tag.
Rule: Provide URLs with readable text (e.g. http://codingrules.blogspot.com/2010/06/unit-testing.html) or keywords to access a webpage and not auto generated text or numbers (e.g. http://codingrules.blogspot.com/2010/06/20006.html).
Rule: Regularly check for broken links and remove the same.
Rule: Provide naturally flowing hierarchy for navigation and text for navigation. Avoid drop down menu, images or animation for navigation.
Rule: Provide site map for the user.
Rule: Submit your website's site map (xml format) with Google's webmaster tools for search engine to index your website. Generate XML site map for your website from http://www.xml-sitemaps.com/. Also Google's webmaster tools help webmasters better control how Google interacts with their websites and get useful information from Google about their site.
Rule: Provide custom 404 page, which can guide user back to a working page.
Rule: Write easy to read text content. Avoid images for textual content.
Rule: Try to use words and phrases on the webpage which the user would be looking for.
Rule: Use descriptive anchor text for links.
Rule: Format links to make it easy for users to distinguish between regular text and the anchor text of links.
Rule: Links on your page maybe internal—pointing to other pages on your site—or external—leading to content on other sites. In either of these cases provide descriptive anchor text for better user experience. Anchor text is the clickable text that users will see as a result of a link,
and is placed within the anchor tag <a href="..."></a>.
Rule: Do not design you entire webpage (or website) as image. Provide some text on the webpage which can be indexed by search engines.
Rule: Use descriptive name for images and not like "img1.png" or "pic.png".
Rule: Provide "alt" and "title" attribute text in the "img" tag (<img alt="" title="" src="" />).
Rule: Use "heading" tags (h1 to h6) to emphasize important text.
Rule: If the company name or the website name is embedded as image, then make sure the same is made available as text in the webpage (e.g. "title" tag or description "meta" tag etc).
Rule: For webpages with photo gallery, apart from providing image "alt" and "title" text, let the users to provide comments, which will increase the textual content of the webpage. But make sure to moderate the user comments.
Rule: User comments section can improve the textual content of the webpage. Moderate the user comments to avoid spam content.
Rule: Provide "Related links" section of links with in your website to increase the traffic to your website.
Rule: Provide complete address of your company on the website either on one of the webpage or on all the pages.
Rule: Use the company/product/service information, where ever applicable, instead of using we or our.
There are no hard and fast rules as far as naming conventions are concerned, but it has to be consistent at the individual, team and organization level.
The name of the folder, project, file, namespace, class, and function have to be meaningful. The variable (data members, local members or function arguments) must have the following information as part of their name
modifier (private, public, etc.) and scope of the variable (member to the class (data member), member to the function (local variable), constant, static)
datatype of the variable
meaningful name
Along with the above mentioned points you can also add comments where ever necessary. Also indentation of the code would improve the readability.
C# 2.0 example- Below is the Employee.cs file.
using System;
using System.Collections.Generic;
using System.Text;
namespace Sample_v2
{
class Employee
{
private string m_strName=String.Empty;
private int m_iEmpId=-1;
public Employee(string strName, int iEmpId)
{
m_strName = strName;
m_iEmpId = iEmpId;
}
public string Name
{
get
{
return m_strName;
}
private set { m_strName = value; }
}
public int EmpId
{
get
{
return m_iEmpId;
}
private set { m_iEmpId = value; }
}
//should not allow empty string or null string
public bool SetNameWithValidation(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
m_strName = strName;
blnStatus = true;
}
return blnStatus;
}
public override string ToString()
{
return string.Format("Name:{0},EmpId:{1}",
m_strName, m_iEmpId);
}
}
}
C# 3.0 example- Below is the Employee.cs file.
using System;
using System.Collections.Generic;
using System.Text;
namespace Sample_v3
{
class Employee
{
public string Name { get; set; }
public int EmpId { get; set; }
public Employee()
{
}
//should not allow empty string or null string
public bool SetName(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
Name = strName;
blnStatus = true;
}
return blnStatus;
}
public override string ToString()
{
return string.Format("Name:{0},EmpId:{1}",
Name,
EmpId);
}
}
}
Note: Alternatively you can follow the naming standard followed by the respective technology (.Net, J2SE, JavasScript, etc). Intellisense feature of the respective integrated development environment (IDE) could help you on this.
Rule: Follow consistent naming convention.
Rule: If you not clear on the final name of the product, module, etc consider using a meaning less code name (e.g. "code123").
Xml is one of most popular format for storing and exchanging data.
For example if we want to store address in an xml file then it would look some thing as below
Keeping the tag name shot reduces the overall xml file size. Also have bandwidth advantage if transfered across the network.
Create an xml file with normal tag names with 10000 Contact nodes. Create another xml file with short tag names with 10000 C nodes.
Output:
The size of the xml file with normal tag name is approximately 2.08 MB.
The size of the xml file with short tag name is approximately 1.57 MB.
Below is an example of xml file with short attribute name.
Initialize the failure status value to return variable. So that even if the success value is not set to the return value, the call would always fail and the developer can debug and fix the issue during unit testing or development.
C# example- In the below example blnStatus is initialized to false.
//should not allow empty string or null string
public bool SetName(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
Name = strName;
blnStatus = true;
}
return blnStatus;
}
Rule: Initialize the return variable to failure status value.
Rule: Make sure return variable is set to success status value at the right place.
If you are developing a multi threaded application. Make sure you code is thread safe. For better performance try to protect only the resource being accessed for reading or writing across threads and some lines of code.
C#- Make sure the mutex, monito or semaphore, if used, are released properly.
Note: A semaphore with a capacity of one is similar to mutex or lock. Semaphore is thread-agnostic because it has no owner. Any thread can call release a semaphore, but with lock and mutex, only the thread that acquired the resource can release it.
C# example- Below Logger class covers using lock and monitor, releasing monitor and protecting only the resource being shared across threads.
class Logger
{
public string FilePath { get; set; }
private StreamWriter m_objStreamWriter = null;
private object m_objLocker;
public Logger()
{
m_objLocker=new object();
FilePath = @"d:\log.txt";
}
public bool Open()
{
bool blnStatus = false;
try
{
m_objStreamWriter = new StreamWriter(FilePath, true);
blnStatus = true;
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
public bool Close()
{
bool blnStatus = false;
try
{
if (m_objStreamWriter != null)
{
m_objStreamWriter.Close();
blnStatus = true;
}
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
//make sure Open is called before calling WriteToFile
//make sure Close is called once all logging is done
public bool WriteToFile(string strMessage)
{
bool blnStatus = false;
if (strMessage != string.Empty && strMessage != null)
{
try
{
lock (m_objLocker)
{
if (m_objStreamWriter != null)
{
//logs only the time and not the date
m_objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay
+ " - "
+ strMessage
);
blnStatus = true;
}
}
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
}
return blnStatus;
}
//make sure the StreamWriter is closed
//make sure thr Monitor is exit
public bool WriteToFile_Local(string strMessage)
{
bool blnStatus = false;
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
try
{
Monitor.Enter(m_objLocker);
objStreamWriter = new StreamWriter(FilePath,
true);
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " + strMessage
);
objStreamWriter.Close();
Monitor.Exit(m_objLocker);
blnStatus = true;
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
if (objStreamWriter != null)
{
objStreamWriter.Close();
}
Monitor.Exit(m_objLocker);
}
finally
{
}
}
return blnStatus;
}
//exception has to be handled by the caller
//can not be unit tested using UnitTestingTool class
public void WriteToFile_Local_Using(string strMessage)
{
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
//private member variable
lock (m_objLocker)
{
using (objStreamWriter =
new StreamWriter(FilePath, true))
{
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " +
strMessage
);
}
}
}
}
}
Rule: Write thread safe code if your application is multi threaded.
Rule: Protecting only the resource being shared across threads or processes.
Rule: Releasing the mutex, monitor or semaphore if used.
Make sure you release all the used resource. Below are some of the examples
closing the database connection
closing the file handle
closing the communication port (RS232, Socket, USB, UDP, etc)
C#- If you are using try catch block, make sure you have
the finally block to release the resources. In some case the resource may
have to be released in catch block. Otherwise the “Using”
(gets compiled to try/finally block) block can be used.
C# example- Below code has StreamWriter and try/catch/finally block.
//make sure the StreamWriter is closed
//make sure thr Monitor is exit
public bool WriteToFile_Local(string strMessage)
{
bool blnStatus = false;
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
try
{
Monitor.Enter(m_objLocker);
objStreamWriter = new StreamWriter(FilePath, true);
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " + strMessage
);
objStreamWriter.Close();
Monitor.Exit(m_objLocker);
blnStatus = true;
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
if (objStreamWriter != null)
{
objStreamWriter.Close();
}
Monitor.Exit(m_objLocker);
}
finally
{
}
}
return blnStatus;
}
C# example- Below code has StreamWriter and Using block.
//exception has to be handled by the caller
//can not be unit tested using UnitTestingTool class
public void WriteToFile_Local_Using(string strMessage)
{
StreamWriter objStreamWriter = null;
if (strMessage != string.Empty && strMessage != null)
{
//private member variable
lock (m_objLocker)
{
using (objStreamWriter =
new StreamWriter(FilePath, true))
{
//logs only the time and not the date
objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay + " - " + strMessage
);
}
}
}
}
Note: When you are done with the reference variable it need
not be set to null, because once a variable fall out of scope,
it is popped from the stack and the reference is removed.
If you are using try/catch block for handling exception then make sure the catch block handles the exception. It can be showing a message to the user and/or logging the exception details to a log file along with realsing the resources and transcation rollbacks.
Rule: Handle the exception in the catch block.
Rule: Rollback transaction in the catch block if applicable.
Do not hardcode any values (numbers and string used with in application). Use a separate file for declaring and defining the constant values either at the assembly (module) level or at the application level.
C# example- In the below example constants class is used for storing all the constants.
class Constants
{
public const int MinEmpId = 0;
}
//employee class
class Employee
{
public string Name { get; set; }
public int EmpId { get; }
public Employee()
{
}
//should not allow negative numbers
public bool SetEmpId(int iEmpId)
{
bool blnStatus = false;
if (iEmpId >= Constants.MinEmpId)
{
EmpId = iEmpId;
blnStatus = true;
}
return blnStatus;
}
}
Note: Follow the internationalization standards if your application has to support localization.
Rule: Do not hardcode values.
Rule: Follow internationalization standards if required.
Validate the function arguments for the following
1) null or empty value
2) invalid datatype
3) out of range if applicable
Alternatively you can validate the arguments in the calling function and have called function perform only the business logic.
C# example
//should not allow empty string or null string
public bool SetName(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
Name = strName;
blnStatus = true;
}
return blnStatus;
}
Note: The intranet applications can handle the argument validations before calling the function in the server so that the server can focus only on executing the business logic.
Due to security reasons the internet applications should authenticate the caller, authorize the caller and validate the function arguments.
Rule: Validate the arguments for null or empty values.
Make sure the application has a logging mechanism. Consider the following while designing and implementing the logging functionality
Log only the exceptions which can not be handled by the end user and provide proper guidance for the end user to report the same.
Logging functionality shall be controlled through external configuration for enabling and disabling.
Alternatively the logging functionality shall be controlled through different build configurations like debug build with logging enabled and release build with logging disabled.
Logging mechanism for debugging the code (code flow) has to be disabled in the production version. The logging can be enabled if any crash is reported in the production version.
Do not use text file logging mechanism for recording audit trail information (user actions, transactions, etc.) instead use a database.
If the logs are recoded in test files consider a proper archival mechanism, so that the log file does not grow to the extend which can not be opened by any text file viewer.
Logging functionality has to be thread safe so that it can be used in multiple threaded application.
If the log information can be sent to an UDP port, then an UDP client application can be used for viewing the log information online.Overall this can make the debugging process very effective. Also this approach can be used for remote debugging if possible.
Make sure the logging functionality is optimized to the maximum.
The below unit testing example has UnitTestingTool class, Logger class and few unit test cases for the Logger class.
UnitTestingTool is the class used for unit testing.
It supports testing function which returns bool, object,
string data types. It also has the counts of passed and failed test cases.
The pass and fail counts can be reset to zero and also displayed on the console.
Logger is the class which is unit tested.
The Logger class is used for logging string message to a text file.
The Logger class function call sequence is
Create Logger object
Call Open function
Call WriteToFile function
Call Close function
C# example- Simple unit testing tool.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
namespace UTLogger
{
//unit testing tool class
class UnitTestingTool
{
private int m_iPassCount = 0;
private int m_iFailCount = 0;
public UnitTestingTool()
{
}
public void Reset()
{
m_iPassCount = 0;
m_iFailCount = 0;
}
public bool ValidateBool(bool blnResult,
bool blnExpectedResult, string strRemarks)
{
bool blnStatus = false;
StringBuilder objSBResult = new StringBuilder();
if (blnExpectedResult == blnResult)
{
m_iPassCount++;
blnStatus = true;
}
else
{
m_iFailCount++;
objSBResult.AppendLine("Bool test failed:"
+ strRemarks);
objSBResult.AppendLine("Result:"
+ blnResult);
objSBResult.AppendLine("Expected Result:"
+ blnExpectedResult);
Console.WriteLine(objSBResult);
}
return blnStatus;
}
public bool ValidateObject(object objResult,
object objExpectedResult, string strRemarks)
{
bool blnStatus = false;
StringBuilder objSBResult = new StringBuilder();
if (objExpectedResult == objResult)
{
m_iPassCount++;
blnStatus = true;
}
else
{
m_iFailCount++;
objSBResult.AppendLine("Object test failed:"
+ strRemarks);
objSBResult.AppendLine("Result:"
+ objResult);
objSBResult.AppendLine("Expected Result:"
+ objExpectedResult);
Console.WriteLine(objSBResult);
}
return blnStatus;
}
public bool ValidateString(string strResult,
string strExpectedResult, string strRemarks)
{
bool blnStatus = false;
StringBuilder objSBResult = new StringBuilder();
if (strExpectedResult == strResult)
{
m_iPassCount++;
blnStatus = true;
}
else
{
m_iFailCount++;
objSBResult.AppendLine("string test failed:"
+ strRemarks);
objSBResult.AppendLine("Result:"
+ strResult);
objSBResult.AppendLine("Expected Result:"
+ strExpectedResult);
Console.WriteLine(objSBResult);
}
return blnStatus;
}
public void DisplayResult()
{
StringBuilder objSBResult = new StringBuilder();
objSBResult.AppendLine("Test result");
objSBResult.AppendLine("------------------------");
objSBResult.AppendLine("Pass count:" + m_iPassCount);
objSBResult.AppendLine("Fail count:" + m_iFailCount);
objSBResult.AppendLine("------------------------");
objSBResult.AppendLine("Total count:"
+ (m_iPassCount + m_iFailCount));
Console.WriteLine(objSBResult);
}
}
class Logger
{
public string FilePath { get; set; }
private StreamWriter m_objStreamWriter = null;
private object m_objLocker;
public Logger()
{
m_objLocker=new object();
FilePath = @"d:\log.txt";
}
public bool Open()
{
bool blnStatus = false;
try
{
m_objStreamWriter = new StreamWriter(FilePath, true);
blnStatus = true;
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
public bool Close()
{
bool blnStatus = false;
try
{
if (m_objStreamWriter != null)
{
m_objStreamWriter.Close();
blnStatus = true;
}
}
catch (Exception objEx)
{
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
return blnStatus;
}
//make sure Open is called before calling WriteToFile
//make sure Close is called once all logging is done
public bool WriteToFile(string strMessage)
{
bool blnStatus = false;
if (strMessage != string.Empty && strMessage != null)
{
try
{
lock (m_objLocker)
{
if (m_objStreamWriter != null)
{
//logs only the time and not the date
m_objStreamWriter.WriteLine(
DateTime.Now.TimeOfDay
+ " - "
+ strMessage
);
blnStatus = true;
}
}
}
catch (Exception objEx)
{
//use messagebox if winforms application
Console.WriteLine(objEx.StackTrace);
}
finally
{
}
}
return blnStatus;
}
}
class Program
{
static void Main(string[] args)
{
Logger objLogger = null;
UnitTestingTool objUTT = null;
objLogger = new Logger();
objUTT = new UnitTestingTool();
bool blnStatus = false;
blnStatus = objUTT.ValidateBool(
objLogger.WriteToFile(""),
false,
"EmptyString Message"
);
if (true == blnStatus)
{
blnStatus=objUTT.ValidateBool(
objLogger.WriteToFile(null),
false,
"null Message"
);
}
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.WriteToFile("test1"),
false,
"Valid Message without opening the logger"
);
}
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.Close(),
false,
"Close objLogger without opening"
);
}
//invalid filepath
objLogger.FilePath = @"z:\log.txt";
//expect the exception message on the console
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.Open(),
false,
"Open objLogger with invalid filepath"
);
}
//valid filepath
objLogger.FilePath = @"d:\log.txt";
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.Open(),
true,
"Open objLogger with valid filepath"
);
}
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.WriteToFile("test1"),
true,
"Valid Message"
);
}
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.WriteToFile("test2"),
true,
"Valid Message"
);
}
if (true == blnStatus)
{
blnStatus = objUTT.ValidateBool(
objLogger.Close(),
true,
"Close objLogger"
);
}
objUTT.DisplayResult();
Console.ReadLine();
}
}
}
Output:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, I
nt32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions o
ptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access,
FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamWriter.CreateFile(String path, Boolean append)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encodin
g, Int32 bufferSize)
at System.IO.StreamWriter..ctor(String path, Boolean append)
at UTLogger.Logger.Open() in D:\code2009\Sample\UTLogger\Program.cs:line 121
Test result
------------------------
Pass count:9
Fail count:0
------------------------
Total count:9
Note: The above UnitTestingTool class can be extended for other data types.
Generally the developers tend to write the code which works only for valid user input or arguments and end up releasing the same for testing (no unit testing, no refactoring and no optimization). C# example Step #1 - Write the code for all possible invalid condition.
//should not allow empty string or null string
public bool SetName(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
}
return blnStatus;
}
Step #2 - Perform a quick unit test.
Example unit test cases.
Test the code for empty string and expect the function to return false
Test the code for null string and expect the function to return false
If any of the above case fails fix the code without writing the code for invalid case
When all the above cases succeed write the code for valid case
Step #3 - Fix the defects and verify the fixes if any.
C# example
Step #4 - Write the code for all valid conditions.
//should not allow empty string or null string
public bool SetName(string strName)
{
bool blnStatus = false;
if (strName != string.Empty && strName != null)
{
m_strName = strName;
blnStatus = true;
}
return blnStatus;
}
Step #5 - Perform the unit test for the entire functionality.
Example unit test cases.
Test the code for empty string and expect the function to return false
Test the code for null string and expect the function to return false
Next add the test case for valid string value and expect the function to return true
If any of the above case fails fix the code and verify the same
Step #6 - Fix the defects and verify the fixes if any.
Write invalid condition code → Unit test → Fix & Verify → Write valid condition code → Unit test → Fix & Verify
Note: Unit testing automation strategy has to planned well before starting the implementation. There are unit testing automation frameworks available in the open source community as well as COTS.
Make sure the public function returns some value or reference or status of the execution. So that the function can be unit tested.
C# example- Below is a non testable function.
//should not allow value less than 1 and greater than 100
public void SetAge(int iAge)
{
if (iAge >= 1 && iAge <= 100)
{
m_iAge = iAge;
}
}
The above function, if called gets executed but the caller would not be sure about the result of execution, so the caller has to get the age again and check if it was set correctly. C# example- Below is a testable function.
//should not allow value less than 1 and greater than 100
public bool SetAge(int iAge)
{
bool blnStatus = false;
if (iAge >= 1 && iAge <= 100)
{
m_iAge = iAge;
blnStatus = true;
}
return blnStatus;
}
Note: Minimize coupling (dependency between classes and modules) as much as possible, which could highly improve the testability of the entire module.