Use the Bash Shell script to function test
Save time and energy during the molding process of your application
Angel Rivera (Rivera@us.ibm.com) Software Engineer, Visualage Teamconnection, IBM 2001 March
content:
Transplant script from Korn to Bash to create script Run Script Reference About Authors Reviews This article
Functional testing is a key part of software development - and Bash that has been loaded with Linux can help you complete functional testing. In this article, Angel Rivera will explain how to use the Bash Shell script through the row command to perform the functional test of the Linux application. Since this script relies on the return code of the command line, you cannot use this method to the GUI application.
Functional testing is a phase of the development cycle, which will test the software application to ensure that the software's functions are expected, and can also process errors in the code. This work typically performs system testing of the entire product under load / heavy pressure conditions after the unit test of a single module.
There are many test tools on the market to provide functional testing. However, first you have to get them, then install, configure, which will take up your valuable time and energy. Bash can help you avoid these cumbersome things so that you can speed up your test.
The advantage of function testing using the Bash Shell script is:
Bash shell scripts have been installed and configured in the Linux system. Don't take time to prepare it again. The Bash Shell script can be created and modified by a text editor provided by Linux such as VI. There is no need to get a special tool for creating a test program. If you already know how to develop Bourne or Korn shell scripts, it is enough for how to use the Bash Shell script. For you, the learning curve does not exist. Bash Shell provides a large number of programming structures for developing from very simple to medium complex scripts.
Recommendations when you transplant the script from Korn to Bash If you have a ready-made Korn shell script, you want to put them to BASH, you need to consider the following:
Korn's "print" command cannot be used in Bash; it is changed to use the "echo" command. Need to modify the first line of the script: #! / Usr / bin / ksh: #! / Bin / bash
Creating a Bash Shell script for feature testing these basic steps and suggests that there are many client / server applications running on Linux.
Recording the prerequisites and main steps of the run script and divide the operation into several logical groups Based on the General Scheme. Ensure steps provide comments in each shell script and explain to create a starting backup to create a baseline check Input parameter and environment variable attempt to provide "USUGE "Feedback Attempts to provide a" quiet "run mode When an error occurs, a function termination script is provided, providing functions that can perform a single task when displaying the output being generated, capturing the output of each script in each script In the output file, the number of returned code calculation failed transactions in the output file, highlighting the error message, in order to identify if possible, "real-time" generation files provide feedback to provide feedback to provide a summary of the script execution in the execution script An easy explanatory output file is likely to provide a clear script and a method of returning a baseline
Each suggestion and a script for explaining a problem will be described in detail below. To download this script, see the reference part of this article.
1. Record the prerequisites and primary steps of running scripts, especially with a single file with self-whit (such as "Readme-Testing.txt") Record function test, including, such as prerequisites, servers And client settings, scripts follow the entire (or detailed) step, how to check the success / failure of the script, how to perform clear and restart tests. 2. Divide the operation into a number of logical groups If only the number of operations are implemented, they can put all them in a simple shell script.
However, if you need to perform some of the number of operations, it is best to divide them into several logical collections, such as placing some server operations in a file and putting client operation in another file. In this way, the appropriate particle size is divided to perform testing and maintenance tests.
3. Based on the general solution, the execution step is determined to packet the operation, and the step of performing the operation is required according to the general solution. This idea is to simulate the situation of end users in actual life. As an overall principle, only 20% of the most frequently called functions of 80% is required.
For example, assume that the application requires that three test groups are arranged in a particular order. Each test group can be placed in a file with a self-description file name (if possible), and use the number to help identify the order of each file, for example:
1. FVT-SETUP-1: TO Perform Initial setup.
2. FVT-Server-2: To Perform Server Commands.
3. FVT-Client-3: To Perform Client Commands.
4. FVT-CLEANUP: To Cleanup The Temporary Files,
In Order to Prepare for the Repetition
Of The Above Test Case.
4. Provides annotations and descriptions in each shell script that provides relevant annotations and descriptions in each shell script and description is a good coding habit. In this case, when another tester runs the script, the tester can clearly understand the scope of each script, all prerequisites and warnings.
Below is an example of a Bash script "Test-Bucket-1".
#! / bin / bash
#
# Name: Test-bucket-1
#
# P p:
# Performs The Test-Bucket Number 1 for Product X.
# (Actually, this Is A Sample Shell Script,
# Which invokes some system commands
# To illustrate how to construct a Bash Script)
#
# Notes:
# 1) The Environment Variable Test_var Must Be Set
# (as an example).
# 2) TO Invoke this Shell Script and Redirect Standard
# Output and standard error to a file (Such as
# Test-bucket-1.out) Do The Following (The --s Flag
# i "Silent Mode" to Avoid Prompts to the user):
#
# ./test-bucket-1 -s 2> & 1 | TEE TEST-BUCKET-1.out
#
# RETURN CODES:
# 0 = all commands around successful # 1 = at Least One Command Failed, See The Output File
# and search for the keyword "error".
#
######################################################################################################################################################################################################################################################################################################## ######
5. Do a initial backup to create a baseline you may need to perform functional testing multiple times. When you run it for the first time, some errors in the script or process may be found. Thus, in order to avoid a lot of time due to the recreation server environment - especially if it involves the database - you may want to make a backup before the test.
After running the function test, you can restore the server from the backup, and it is also prepared for the next round of testing.
6. Check the input parameters and environment variables to check the input parameters and check if the environment variable is set correctly. If there is a problem, the cause of the problem is displayed and the method thereof, and then the script is terminated.
When the tester is ready to run the script, but at this time, if the environment variable called correctly is set, since it is found in time, the tester will be quite grateful. No one likes to wait for the script to execute for a long time, but I find that the variable is not set correctly.
# --------------------------------------------
# Main routine for performing the test bucket
# --------------------------------------------
Caller = `basename $ 0` # The caller name
Silent = "no" # User Wants Prompts
Let "errorcounter = 0"
# ----------------------------------
# Handle Keyword Parameters (Flags).
# ----------------------------------
# For more sophistated usage of getopt in Linux,
# See the samples file: /usr/lib/getopt/parse.bash
Temp = `Getopt HS $ *`
IF [$?! = 0]
THEN
echo "$ CALLER: Unknown Flag (s)"
USAGE
Fi
# Note Quotes Around `$ TEMP ': They Are Essential!
Eval Set - "$ TEMP"
While True
DO
Case "$ 1" in
-H) Usage "help"; shift ;; # Help Requested
-S) Silent = "yes"; shift ;; # prompt not needed
-) SHIFT; BREAK ;;
*) Echo "Internal Error!"; EXIT 1 ;;
ESAC
DONE
# -------------------------------------------------
# The Following Environment Variables Must Be Set
# -------------------------------------------------
IF [-z "$ test_var"]
THEN
Echo "Environment Variable Test_var is not set." usage
Fi
The description of this script is as follows:
Use statements Caller = `baseName $ 0` You can get the script name being running. In this case, there is no need to hard coding the script name in the script. Therefore, when copying the script, the newly derived script can reduce the workload. When calling scripts, statement temp = `getOpt HS $ *` is used to get input variables (such as -h represents help, -s represent quiet mode). Statements [-z "$ x"] and echo "The Environment Variable X IS Not set." And usage are used to detect whether the string is empty (-z), if it is empty, then execute the ECHO statement to display Set the string and call the "Usage" function to be discussed below. If the script does not use the flag, you can use the variable "$ #", which can return the number of variables that are passing to the script.
7. Try to provide the "USAGE" feedback script to use the "usage" statement is a good idea, which is used to explain how to use the script.
# ----------------------------
# Subroutine to echo the usage
# ----------------------------
USAGE ()
{
echo "USAGE: $ CALLER [-H] [-s]"
echo "where: -h = HELP"
echo "-s = silent (no prospts)"
echo "prerequisites:"
echo "* The Environment Variable Test_var Must Be set,"
echo "* Such as:"
echo "export test_var = 1"
Echo "$ CALLER: EXITING NOW with RC = 1."
EXIT 1
}
When calling the script, use the "-h" flag to call the "usage" statement as follows: ./ Test-bucket-1 -h
8. Try using the "quiet" run mode you might want to make the script have two run modes:
In the "verbose" mode (you may want to turn this as the default value) prompt the user into the value, or just press Enter to continue running. The user is not prompted in the "Silent" mode.
The following excerpts illustrate the use of the called flag "-s" in quiet mode to run the script:
# -------------------------------------------------
# Everything Seems OK, Prompt for Confirmation
# -------------------------------------------------
IF [$ Silent "=" YES "]
THEN
Response = "y"
Else
echo "The $ Caller Will Be Performed."
echo "do you wish to proced [y or n]?"
Read Response # Wait For Response [-z "$ response"] && response = "n"
Fi
Case "$ response" in
[YY] | [YY] [EE] | [YY] [EE] [SS])
;
*)
Echo "$ CALLER TERMINATED with RC = 1."
EXIT 1
;
ESAC
9. When an error occurs, providing a function termination script encounters a serious error, providing a central function to terminate the script that is not a good idea. This function can also provide additional instructions for guiding what should be done in this case:
# ----------------------------------
# Subroutine to Terminate AbnorMally
# ----------------------------------
Terminate ()
{
Echo "The Execution of $ Caller WAS Not successful."
Echo "$ CALLER TERMINATED, EXITING NOW WITH RC = 1."
Datetest = `date`
Echo "End of Testing At: $ DateTest"
echo ""
EXIT 1
}
10. If possible, provide functions that can perform simple tasks, for example, do not use many long code, such as:
# ------------------------------------------------- -
echo ""
Echo "CREANG Access Lists ..."
# ------------------------------------------------- -
Access -create -component development -login ted -authority plead -verbose
IF [$? -ne 0]
THEN
Echo "Error Found in Access -Create -component Development -Login TED
-Authority plead
Let "errorcounter = erroorcounter 1"
Fi
Access -create -component development -login pat --authority general -verbose
IF [$? -ne 0]
THEN
Echo "Error Found in Access -Create -component Development -Login Pat
-Authority General
Let "errorcounter = erroorcounter 1"
Fi
Access -create -component development -login jim -authority general -verbose
IF [$? -ne 0]
THEN
Echo "Error Found in Access -Create -component Development -Login Jim
-Authority General
Let "errorcounter = erroorcounter 1"
Fi
... but create a function as shown below, this function can also handle the return code, if necessary, you can also add an error counter: createAccess ()
{
Access -create -component $ 1 -Login $ 2 - Abrity $ 3 - VERBOSE
IF [$? -ne 0]
THEN
Echo "Error Found in Access -Create -component $ 1 -Login $ 2 - AUTHORITY $ 3"
Let "errorcounter = erroorcounter 1"
Fi
}
...... then call this function with easy-to-read and easy expansion:
# -------------------------------------------
echo ""
Echo "CREANG Access Lists ..."
# -------------------------------------------
CreateAccess Development TED Projectlead
CreateAccess Development Pat General Pat General
CreateAccess Development Jim General
11. When displaying the output being generated, the output of each script can be used if the script cannot send the output to the file, and some of the Bash Shell can capture the output of the executed script, such as:
./test-bucket-1 -s 2> & 1 | TEE TEST-BUCKET-1.out
Let us analyze the above command:
"2> & 1" command: Use "2> & 1" to redirect the standard error to the standard output. String "2> & 1" indicates that any errors should be sent to standard output, that is, the file ID of UNIX / Linux 2 represented standard errors, and the file identity represents the standard output. If you don't have to use this string, the captured is just correct information, and the error message will be ignored. Pipe "|" and "TEE" commands: UNIX / Linux process and simple pipeline concepts are very similar. In this case, you can do a pipe to output the output of the script as the input of the pipe. The next thing to decide how to handle the content output from the pipe. In this case, we will capture it into the output file, referred to in this example to "Test-Bucket-1.out". However, in addition to capturing the output results, we also want to monitor the output generated by the script run. To achieve this, we connect to "TEE" (T--shaped pipeline) that allows two things to be carried out: put the output results in the file and display the output results on the screen. Its pipe is similar to: Process -> T ---> Output File
|
V
Screen
If you only want to capture the output results instead, you can ignore the extra pipeline: ./test-bucket-1 -s 2> & 1> Test-bucket-1.out false If this is like this, similar pipe As follows: Process -> Output File
12. In each script, a way to capture the success of each line command is determined that the function test is successful or failed is to calculate the number of failure line commands, ie the return code is not 0. Variable "$?" Provides a return code for the recent call command; in the example below, it provides a return code for executing the "LS" command. # -------------------------------------------
# THE COMMANDS Are Called in a SUBROUTINE
# So That Return Code Can Be
# Checked for Possible Errors.
# -------------------------------------------
Listfile ()
{
Echo "LS -AL $ 1"
LS -AL $ 1
IF [$? -ne 0]
THEN
Echo "Error Found in: ls -al $ 1"
Let "errorcounter = erroorcounter 1"
Fi
}
13. A number of records that failure transactions decide to success or fail in functional testing is to calculate the number of line commands that return the return value is not 0. However, from my personal experience, I am used to using only a string in my Bash Shell script instead of integers. Didn't clearly explain how to use an integer in the manual I have referred to, this is why I want to have more than how to use an integer and calculation error (line command failure):
First, you need to initialize the counter variables as follows:
Let "errorcounter = 0"
Then, issue a line command and use the $? Variable to capture the return code. If the return code is not 0, then the counter adds 1 (see blue bold statement):
Listfile ()
{
Echo "LS -AL $ 1"
LS -AL $ 1
IF [$? -ne 0]
THEN
Echo "Error Found in: ls -al $ 1"
Let "errorcounter = erroorcounter 1"
Fi
}
By the way, like other variables, you can use "ECHO" to display integer variables.
14. In the output file, in order to easily identify, highlight the error message When an error (or failed transaction) is encountered, the number of error counters will increase, it is best to identify this is wrong. Ideally, the string has a substring such as Error or a similar sub-string (see blue bold statement), which allows the tester to quickly find errors in the output file. This output file may be very large, and it is very important to quickly find the error.
Listfile ()
{
Echo "LS -AL $ 1"
LS -AL $ 1
IF [$? -ne 0]
THEN
Echo "Error Found in: ls -al $ 1"
Let "errorcounter = erroorcounter 1"
Fi
}
15. If possible, "Real Time" generation files are necessary to handle the files used by the application in some cases. You can use an existing file or you can add a statement to the script to create a file. If the file to be used is long, it is best to use it as an independent entity. If the file is small and the content is simple or not related (important point is a text file without considering its content), you can decide "Real Time" to create these temporary files.
The following line of code shows how to "real-time" creation temporary files:
CD $ HOME / FVT
Echo "Creating File Softtar.c"
Echo "Subject: this is software"> SoftTar.c
Echo "this is line 2 of the file" >> SoftTar.c
The first ECHO statement uses a single> forcibly created a new file. The second ECHO statement uses two >> attach data to the back of the existing file. By the way, if the file does not exist, you will create a file.
16. Provides feedback during the execution of the script is best to include the Echo statement in the script to indicate the logical progress thereof. You can add some statements that can quickly indicate the output purpose.
If the script takes some time to execute, it may be printed at the beginning and end of the execution script. This can calculate the time taken.
In the script sample, some of the Echo statements that provide progress are as follows:
# --------------------------------------------
Echo "Subject: Product X, FVT Testing"
Datetest = `date`
Echo "Begin Testing At: $ DateTest"
echo ""
Echo "Testcase: $ Caller"
echo ""
# --------------------------------------------
# --------------------------------------------
echo ""
Echo "Listing Files ..."
# --------------------------------------------
# The folload file shouth be listed:
Listfile $ homen / .profile
...
# --------------------------------------------
echo ""
Echo "CREATING FILE 1"
# --------------------------------------------
17. Summary of providing scripts If you are calculating an error or failure, it is best to indicate whether there is an error. This method allows the tester to quickly recognize whether there is an error in the end of seeing the output file.
In the following script example, the code statement provides a summary of the above script:
# ----------------
# Exit
# ----------------
IF [$ errorcounter -ne 0]
THEN
echo ""
echo "*** $ ErrorCounter Erroors Found During ***"
echo "*** The Execution of this test case. ***"
Terminate
Else
echo ""
echo "*** yeah! no errors be ford during ***"
Echo "*** The Execution of this test case. Yeah! ***"
Fi
echo ""
Echo "$ CALLER Complete."
echo ""
Datetest = `date`
Echo "End of Testing at: $ datetest" echo ""
EXIT 0
# END OF FILE
18. Provides a easy interpretation of output files to provide some key information in the actual output of scripts. In that, the tester can easily determine if the file being viewed is related to what you do, and whether it is currently generated. Additional timestamp is important for whether it is the current state. Summary Report is also very helpful for determining whether there is an error; if there is an error, the tester must search for the specified keyword, such as Error, and confirm individual failures.
The following is a fragment of a sample sample:
Subject: CMVC 2.3.1, FVT Testing, Common, Part 1
Begin Testing At: Tue Apr 18 12:50:55 Edt 2000
Database: DB2
Family: CMPC3DB2
Testcase: FVT-Common-1
CREANG USERS ...
User Pat Was CREATED SUCCESSFULLY.
...
Well Done! No Errors WERE Found During the
Execution of this test case :)
FVT-Common-1 COMPLETE.
End of testing at: Tue Apr 18 12:56:33 EDT 2000
An example of the last part of the output file when you encounter an error:
ERROR FOUND in Report -view DefectView
*** 1 Errors Found During The Execution of this Test case. ***
The Populate Action for the CMVC Family Was Not Successful.
RECRETING THE FAMILY May Be Necessary BEFORE
Running FVT-Client-3 Again, That IS, You Must Use 'RMDB',
'RMFamily', 'mkfamily' and 'mkdb -d',
THEN ISSUE: FVT-Common-1 And Optionally, FVT-Server-2.
FVT-Client-3 Terminated, Exitation Now with RC = 1.
End of testing at: Wed Jan 24 17:06:06 Est 2001
19. If possible, the method test script that provides the clearance script and the return baseline can generate a temporary file; if this is, it is best to let the script delete all temporary files. This will avoid errors caused by the testers may not delete all temporary files, worse, is deleted by the required files as temporary files.
Bash Shell Scripts of Run Function Test This section describes how to use the Bash Shell script for functional testing. Suppose you have already performed the steps described in the previous section.
Set the necessary environment variables in. Profile or manually specify the following environment variables as needed. This variable is used to explain how to handle it in the script, and the verification of the desired environment variable must be defined before the script execution.
EXPORT TEST_VAR = 1
Copy the Bash Shell script to the correct directory. Bash shell script and related files need to be copied to the directory structure of the user identifier to perform functional test.
Log in into an account. You should be in the home directory. Suppose it is / home / tester. Create a directory for the test case: MKDIR FVT Copy the Bash Shell script and related files. Get a compressed file (see Resources) and put it under $ HOME. Then decompressed it in the following manner: unzip trfvtbash.zip In order to execute this file, change the license of the file: CHMOD U X * Change the name to remove the file: MV Test-bucket-1.Bash Test-bucket-1 run Scripts Perform the following steps to run the script:
Log in to the replicated script with tester's user ID: CD $ HOME / FVT Run from $ HOME / FVT: ./ Test-Bucket-1-S 2> & 1 | Tee Test-Bucket-1.out Look at the end of the output file "Test-Bucket-1.out" and view the conclusions of the summary report.
Reference
Download Trfvtbash.zip, which contains the sample code and tools referenced herein. This tool may be updated later. Try to unlock this file with the Info-Zip software. Because the tool is commonly used, it is recommended that you'd better place the directory of the decompression and compression tool into the PATH, so that all users on the machine can use this tool. How to decompress the file: In order to view content in the compressed file (actually not unpacked and unpacking this file), use: unzip -l trfvtbash.zip command. To solve this compressed file, use: UNZIP TRFVTBSH.ZIP command. Please read Daniel Robbins to publish a series of Bash programming on developerWorks: Part 1, Part 2, and Part 3. Please visit the GNU's Bash homepage. Please refer to the Bash reference manual.
About the author Angel Rivera is a consultant software engineer for a Visualage Teamconnection Technical Support Group, and he is currently the head of the group. He has a master's degree in Electronic Engineering in Austin Texas and a bachelor's degree in Mexico Institutes de Monterrey Electronic System Engineering. He entered IBM in 1989. You can contact him through rivera@us.ibm.com.
In the process of writing this article, Angel thank Lee Perlov's technical support in WebSphere.