Blog for QuickTest Pro (QTP) posts for experts and contains frameworks and scripts
Difference between Function and Sub
Sub Procedures
Function Procedures
Sub Procedures
A sub procedure is a series of VBScript statements, enclosed by Sub and End Sub statements which perform actions but do not return a value. A sub procedure can take arguments. If a sub procedure doesn’t receive any arguments, its Sub statement must include an empty parenthesis().
The following Sub procedure uses two intrinsic, or built-in, VBScript functions, MsgBox and InputBox , to prompt a user for information. It then displays the results of a calculation based on that information. The calculation is performed in a Function procedure created using VBScript. The Function procedure is shown after the following discussion.
Sub ConvertTemp()
temp = InputBox("Please enter the temperature in degrees F.", 1)
MsgBox "The temperature is " & Celsius(temp) & " degrees C."
End Sub
Function Procedures
A function procedure is a series of VBScript statements enclosed by the Function and End Function statements. A function procedure is similar to a sub procedure but it can return value to the calling function. A function procedure can take arguments (constants, variables or expressions that are passed to it by a calling procedure). If a function procedure has no arguments, it Function statement must include an empty set of parenthesis. A function returns a value by assigning a value to its name in one or more statements of the procedure. Since VBScript has only one base data type, a function always returns a variant.
In the following example, the Celsius function calculates degrees Celsius from degrees Fahrenheit. When the function is called from the ConvertTemp Sub procedure, a variable containing the argument value is passed to the function. The result of the calculation is returned to the calling procedure and displayed in a message box.
Sub ConvertTemp()
temp = InputBox("Please enter the temperature in degrees F.", 1)
MsgBox "The temperature is " & Celsius(temp) & " degrees C."
End Sub
Function Celsius(fDegrees)
Celsius = (fDegrees - 32) * 5 / 9
End Function
Tips:
To get data out of a procedure, you must use a Function. Remember, a Function procedure can return a value; a Sub procedure can't.
A Function in your code must always be used on the right side of a variable assignment or in an expression.
To call a Sub procedure from another procedure, type the name of the procedure along with values for any required arguments, each separated by a comma. The Call statement is not required, but if you do use it, you must enclose any arguments in parentheses.
The following example shows two calls to the MyProc procedure. One uses the Call statement in the code; the other doesn't. Both do exactly the same thing.
Call MyProc(firstarg, secondarg)
MyProc firstarg, secondarg
Notice that the parentheses are omitted in the call when the Call statement isn't used.
Data driven testing using excel in QTP
In this script we are not importing excel sheet to datatable. Directly values are supplied to application from excel sheet.
set ex= CreateObject("Excel.Application")
Set a=ex.Workbooks.open("D:\excel.xls")
Set b=a.worksheets("Sheet1")
dim login, pwd
for i=1 to 3
login=b.Cells(i,"A").value
pwd=b.Cells(i,"B").value
msgbox login
msgbox pwd
next
"D:\excel.xls" is path of excel sheet.
"sheet1" indicates sheet name in which values are present.
A,B are column names in excel sheet.
we have excel sheet with values as shown below in d drive.
A B
1 2
3 4
5 6
Count & Close all browsers
Set ab=Description.Create
ab("micclass").value="Browser"
Set obj=Desktop.ChildObjects(ab)
msgbox obj.count
For i=0 to obj.count-1
c=obj(i).getroproperty("name")
msgbox(c)
obj(i).Close
Next
Descriptive programming example
In this script we will check whether yahoologinpage(www.yahoomail.com) checkbox is checked or not
Set g=Browser("name:=Yahoo.*").Page("title:=Yahoo.*")
Set obj=Description.Create
obj("htmltag").value="Input"
obj("ClassName").value="webcheckbox"
obj("type").value="checkbox"
Set a=g.childobjects(obj)
c=a(0).getroproperty("checked")
msgbox(c)
If c=0 Then
msgbox "checkbox is not checked"
else
msgbox"checkbox is checked"
End If
Data Driven Testing using Notepad in QTP
f=createobject("scripting.filesystemobject")
Set f1=f.createtextfile("d://file1.txt")
f1.writeline"aaa bbb"
f1.writeline"ccc ddd"
f1.writeline"eee fff"
f1.writeline"ggg hhh"
f1.writeline"iii jjj"
The above script creates a notepad in "d" drive with name file1
aaa bbb
ccc ddd
eee fff
ggg hhh
iii jjj
values are stored in file1.txt.
Set f2=f.opentextfile("d://file1.txt")
While f2.atendofstream<>true
f3=f2.readline
x=split(f3," ")
msgbox x(0)
msgbox x(1)
Wend
The above script is used for data driven using notepad directly.here we are not importing data to excel sheet.
directly values are retreived from notepad.
we are using while loop and reading each line till the end.
split function splits the line where space(" ")occurs.
line is divided to 2 parts.one before space and other after space
for example we have 1st line in notepad as aaa bbb
here aaa is 1st part and bbb is 2nd part
x(0)=aaa
x(1)=bbb
all values are read this way using while loop.
One point to note here is if any line is empty in notepad datadriven testing is stopped before that line.
It will not proceed further.so we have to give values without any empty lines in notepad.
To make u more clear,
suppose u have
aaa bbb
ccc ddd
Datadriven is stopped at aaa and bbb only because next line is empty.datadriven is stopped after 1st line.
Some common QTP functions
In this article I captured some functions which are captured from various sources.
How to check for the broken links (both textlinks and image links) on the page with VB script and not the checkpoints.
---------------------------------------------------------
set
obj=Browser("name:=Blackboard.*").Page("title:=Blackboard.*").Frame("name:=main.*").object.all.tags("IMG")
msgbox obj.length
For each element in obj
s1=element.nameProp
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").exist(0) then
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").Object.complete="True" then
msgbox "pass"
else
msgbox "fail"
end if
end if
Next
---------------------------------------------------------
Multiple Exit ways
It’s very easy to control the entry gate to an action or function - there’s only one way to enter them. However, the number of exit gates can vary widely from 1 to many according to the inner logic of the action/function. Today I’m going to address managing multiple exit gates in actions and functions.
When everything goes according to plan, an action flow tends to be very simple. There may be inner loops, If or Select switches, but for the most part, the flow just runs straight down to the last line. The problems usually appear when… well, problems appear. If an application error occurs, or even just an unexpected business logic behavior, there might be no escape from immediately exiting the action. There’s no point trying to input 20 data fields, if the form they’re in didn’t even open, is there?The function is something like the following:
‘.Action Code
If CritialCondition = False Then ExitAction
‘.Continue Action
But this is uninformative. So we add a reporter command:
If CritialCondition = False Then
Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
ExitAction
End If
And we probably got some objects to remove from memory:
If CritialCondition = False Then
Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
oFile.Close
Set oFile = Nothing
ExitAction
End If
============================================
Ho wait, we’ve gathered some data we need to report back:
If CritialCondition = False Then
Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
oFile.Close
Set oFile = Nothing
DataTable("out_EntityID", dtlocalsheet) = sEntityID
‘More here
ExitAction
End If
========================
Well, you probably get the picture. Pretty soon we get massive amounts of code in all the exit gates. This means we have duplicate code to maintain. Duplicate code is the digital manifestation of pure evil – and it’s never a good idea to have pure evil in you actions. Seriously though, this is exactly the kind of things that produces untraceable bugs, and it must be avoided at all cost.
So, how can we deal with this situation? One way is to create an exit gate function. It’s the ONLY function I ever put within an action, and not in an external file. Here’s an example of my action template, with the function:
Dim sResult ‘I store result data and values to be reported up the
‘action-call chain
Dim sActionReport ‘Instead of flooding the log with inner-action messages,
‘I store them, and report all of them at the exit gate.
‘Errors are still reported on-the-fly
‘Action code goes here
‘All the exit gates execute only one command : ActionEnd.
‘It receives two parameters: Boolean for Pass/Fail,
’string for the exit reason
If CriticalCondition = False Then Call ActionEnd(False, "Reason for exiting")
‘Rest of action
‘Even the normal successful action exit is managed through ActionEnd,
’so the last line in every action is:
Call ActionEnd(True, "Action successful")
Sub ActionEnd(bStatus, sReason)
‘Report details
Reporter.ReportEvent MicGeneral, "Inner Action Logs", sActionReport
If bStatus = True Then
Reporter.ReportEvent MicFail, "An error has occurred", sReason
Else
Reporter.ReportEvent MicPass, "Action successful", "See inner logs"
End if
‘Plant datatable info for action-call chain
DataTable("out_Status", dtlocalsheet) = bStatus
DataTable("out_Result", dtlocalsheet) = sResult
‘More if needed
‘Close objects and set to nothing here
‘Other needed exit code
ExitActionIteration
End Sub
With this mechanism, maintaining the exit code becomes very simple, and the logs are much more readable. Ok, so this solves the problem for actions, but what about functions? Well, obviously we can write an inner function within a function, but there is an alternative solution. It’s less elegant than the ActionEnd solution by far, and is harder to maintain, so I recommend using it only in a small number of very complex functions.
The solution is based on the Execute command, so I recommend reading about it in QTP’s help file in case you’re not familiar with it. In a nutshell, the Execute command takes a string, and runs its contents as if it were VBScript code. So for instance the command Execute "msgbox(2)" will pop a message box with the number 2. Here’s an example for the solution, applied to the ComplexFunc function:
Function ComplexFunc
Dim sExitCode
Dim sResult
Dim oFile ‘will be FSO textstream
’separate code lines by vbcrlf or ":"
sExitCode = "oFile.Close" & vbcrlf & _
"Set oFile = Nothing" & vbcrlf & _
"ComplexFunc = sResult"
‘More exit code
‘Function code goes here
‘Exit Gate
If CriticalCondition = False then
sResult = "False, No Connection"
Execute sExitCode
Exit Function
End if
‘More function code
‘Successful exit
Execute sExitCode
End Function
Creating and Calling user define funtion
Test Conditons: Creating and Calling user define funtion
1. Crate small add function and make it compile module.
2. calling that function in other test (using user defined data values)
[ Pre Requesties : Nothing ]
1a. open win runner blank test and add this below data
public function add(in a, in b)
{
return a+b;
}
1b. Go to File menu --> Test Properties (Test Properties window will open)
in General Tab --> Test Type= Compile module and ok
1c.Save the test in some location (Ex c:/tt )
2a.Before writing code , you have to load the funtction in to your folder , globally available to all tests.
2b. Go to Tools menu --> General Options
--- Select Folder option in the left pan.
-- Search Path for called test below enter the path of compile module
(c:/tt) and press "+" button to add in to.
2c. Write down the bleow code in the new test
load("c:/tt");
l= create_input_dialog("Enter First value");
j=create_input_dialog("Enter Second Value");
k=add(l,j);
report_msg(k);
unload("c:/tt");
Verify Broken Links using VBscript (without checkpoints)
So the answer for that was the following code
---------------------------------------------------------
set
obj=Browser("name:=Blackboard.*").Page("title:=Blackboard.*").Frame("name:=main.*").object.all.tags("IMG")
msgbox obj.length
For each element in obj
s1=element.nameProp
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").exist(0) then
If Browser().Page().Frame().Image("file
name:="&s1,"index:=0").Object.complete="True" then
msgbox "pass"
else
msgbox "fail"
end if
end if
Next
---------------------------------------------------------
Code provided by my friend Shiva
Multiple Exit ways
‘.Action Code
If CritialCondition = False Then ExitAction
‘.Continue Action
But this is uninformative. So we add a reporter command:
If CritialCondition = False Then
If CritialCondition = False Then
Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
oFile.Close
Set oFile = Nothing
ExitAction
End If
============================================
If CritialCondition = False Then
Reporter.ReportEvent MicFail, "Something terrible has happened", "Aborting"
oFile.Close
Set oFile = Nothing
DataTable("out_EntityID", dtlocalsheet) = sEntityID
‘More here
ExitAction
End If
Dim sResult ‘I store result data and values to be reported up the
‘action-call chain
Dim sActionReport ‘Instead of flooding the log with inner-action messages,
‘I store them, and report all of them at the exit gate.
‘Errors are still reported on-the-fly
‘Action code goes here
‘All the exit gates execute only one command : ActionEnd.
‘It receives two parameters: Boolean for Pass/Fail,
’string for the exit reason
If CriticalCondition = False Then Call ActionEnd(False, "Reason for exiting")
‘Rest of action
‘Even the normal successful action exit is managed through ActionEnd,
’so the last line in every action is:
Call ActionEnd(True, "Action successful")
Sub ActionEnd(bStatus, sReason)
‘Report details
Reporter.ReportEvent MicGeneral, "Inner Action Logs", sActionReport
If bStatus = True Then
Reporter.ReportEvent MicFail, "An error has occurred", sReason
Else
Reporter.ReportEvent MicPass, "Action successful", "See inner logs"
End if
‘Plant datatable info for action-call chain
DataTable("out_Status", dtlocalsheet) = bStatus
DataTable("out_Result", dtlocalsheet) = sResult
‘More if needed
‘Close objects and set to nothing here
‘Other needed exit code
ExitActionIteration
End Sub
Function ComplexFunc
Dim sExitCode
Dim sResult
Dim oFile ‘will be FSO textstream
’separate code lines by vbcrlf or ":"
sExitCode = "oFile.Close" & vbcrlf & _
"Set oFile = Nothing" & vbcrlf & _
"ComplexFunc = sResult"
‘More exit code
‘Function code goes here
‘Exit Gate
If CriticalCondition = False then
sResult = "False, No Connection"
Execute sExitCode
Exit Function
End if
‘More function code
‘Successful exit
Execute sExitCode
End Function
Creating and Calling user define funtion
| Test Conditons: Creating and Calling user define funtion 2b. Go to Tools menu --> General Options |
Using Database Functions
The code below contains a set of useful functions that can be used in QuickTest Professional.
'Example of how to use functions.
''******************************************************************************************
' Example of how to use DSN created for the database of sample Flight application.
''******************************************************************************************
connection_string="QT_Flight32"
isConnected = db_connect ( curConnection ,connection_string )
' Execute the basic SQL statement
set myrs=db_execute_query( curConnection , SQL )
' Report the query and the connection string
Reporter.ReportEvent micInfo ,"Executed query and created recordset ","Connection_string is ==> " & connection_string & " SQL query is ===> " & SQL
' Show the number of rows in the table using a record set
msgBox " Quantity of rows in queried DB ( db_get_rows_count )==> " & db_get_rows_count( myrs )
' Show the number of rows in the table using a new SQL statement
msgBox " Quantity of rows in queried DB (db_get_rows_count_SQL ) ==> " & db_get_rows_count_SQL( curConnection , "SELECT COUNT(*) FROM ORDERS" )
' Change a value of a field in an existing row
rc = db_set_field_value (curConnection, "ORDERS" , "Agents_Name" , "test", "Agents_Name", "AGENT_TESTER")
' Examples of how to retrieve values from the table
msgBox "val row 0 col 0: " & db_get_field_value( myrs , 0 , 0 )
msgBox "val row 0 col 1: " & db_get_field_value( myrs , 0 , 1 )
msgBox "val row 1 col Name: " & db_get_field_value( myrs , 1 , "Agents_Name" )
msgBox "val SQL row 1 col Name: " & db_get_field_value_SQL( curConnection , "ORDERS" , 1 , "Agents_Name" )
''******************************************************************************************
''******************************************************************************************
' The function creates a new connection session to a database.
' curSession - The session name (string)
' connection_string - A connection string
' for example the connection_string can be "DSN=SQLServer_Source;UID=SA;PWD=abc123"
''******************************************************************************************
Function db_connect( byRef curSession ,connection_string)
set connection = CreateObject("ADODB.Connection")
db_connect= "Error # " & CStr(Err.Number) & " " & Err.Description
connection.Open connection_string
db_connect= "Error # " & CStr(Err.Number) & " " & Err.Description
''******************************************************************************************
' The function disconnects from the database and deletes the session.
' curSession - the session name (string)
''******************************************************************************************
Function db_disconnect( byRef curSession )
''******************************************************************************************
' The function executes an SQL statement.
' Note that a db_connect for (arg1) must be called before this function
' curSession - The session name (string)
''******************************************************************************************
Function db_execute_query ( byRef curSession , SQL)
set rs = curSession.Execute( SQL )
''******************************************************************************************
' ----------------------------
' The function returns the number of rows in the record set
' curRS - Variable, containing a record set, that contains all values that retrieved from the database by query execution
''******************************************************************************************
Function db_get_rows_count( byRef curRS )
''******************************************************************************************
' ------------------------------------
' The function returns the number of rows that are the result of a given SQL statement
' curSession - The session name (string)
''******************************************************************************************
Function db_get_rows_count_SQL( byRef curSession ,CountSQL )
set cur_rs = curSession.Execute( CountSQL )
db_get_rows_count_SQL = cur_rs.fields(0).value
''******************************************************************************************
' -----------------------------------
' curSession - Variable that denotes the current active connection
' tableName - Name of the table, from which the value should be retrieved
''******************************************************************************************
Function db_get_field_value_SQL( curSession , tableName , rowIndex , colName )
SQL = " select " & colName & " from " & tableName
set rs = curSession.Execute( SQL )
db_get_field_value_SQL = rs.fields(colName).value
''******************************************************************************************
' The function returns the value of a single item of an executed query.
' Note that a db_execute_query for (arg1) must called before this function
' curRecordSet - Variable, containing a record set, that contains all values retrieved from the database by query execution
' rowIndex - The row index number (zero-based)
' colIndex - The column index number (zero-based) or the column name.
' -1 - Requested field index more than exists more than once in record set
''******************************************************************************************
Function db_get_field_value( curRecordSet , rowIndex , colIndex )
count_fields = curRecordSet.fields.count-1
If ( TypeName(colIndex)<> "String" ) and ( count_fields < colIndex ) then
db_get_field_value = -1 'requested field index exists more than once in recordset
db_get_field_value = curRecordSet.fields(colIndex).Value
''******************************************************************************************
' The function changes the value of a field according to a search criteria.
' We search for a certain row according to a column name and the desired vale, then we change a value in that row according
' curConnection - The session name (string)
' tableName - Name of the table from which the value should be retrieved
' colFind - The column which to search for the criteria
' colFindValue - The value for which to search in the column
' colChange - The column in which we want to change the value
' colChangeValue - The new value
' -1 - Requested field index that does not exist in the recordset
''******************************************************************************************
Function db_set_field_value(curConnection, tableName , colFind , colFindValue, colChange, colChangeValue)
checkSQL = "select * from Details"
set myrs1 = db_execute_query( curConnection , SQL )
count_fields = myrs1.fields.count
If ( TypeName(colFind)<> "String" ) or ( TypeName(colChange)<> "String" ) then
db_set_field_value = -1 'requested field index that does not exists in the record set
updateSQL = "UPDATE " & tableName & " SET " & colChange & "='" & colChangeValue & "' WHERE " & colFind & "='" & colFindValue & "'"
set myrs1 = db_execute_query( curConnection , updateSQL )
db_set_field_value = 1 'operation suceeded
''******************************************************************************************
' The function adds a new row to the desired table
' curConnection - Variable, containing a recordset, that contains all the values to be retrieved from the database by query execution
' tableName - Name of the table, from which the value should be retrieved
' values - Array that contains values to be entered in a new row to the table
' Note: The function must receive values for all the columns in the table.
' -1 - The number of values to be entered to the table does not match the number of columns
' 1 - Execution of the query succeed and the data was entered to the table
''******************************************************************************************
Function db_add_row(curConnection, tableName , byRef values)
updateSQL = "INSERT INTO " & tableName & " VALUES ("
arrLen = UBound (values) - LBound (values) + 1
set myrs1=db_execute_query( curConnection , SQL )
count_fields = myrs1.fields.count
' Check whether the number of values match the number of columns
If arrLen <> count_fields then
updateSQL = updateSQL & values (i)
set myrs1 = db_execute_query( curConnection , updateSQL )
''******************************************************************************************
' represent_values_of_RecordSet
' ---------------------------------------------
' The function reports all the values of fields in a record set
' curRS - Variable, containing the recordset, that contains all the values that were retrieved from the database by the query execution
''******************************************************************************************
Function represent_values_of_RecordSet( myrs)
reporter.ReportEvent 4,"Fields quantity" , myrs.fields.count
count_fields = myrs.fields.count-1
curRowString = curRowString& "Field " &"==> " & myrs.fields(ii).Name &" : Value ==>" & myrs.fields(ii).Value & vbCrLf
reporter.ReportEvent 4,"Current row"& curRow , curRowString
Using the File System Object (FSO)
The following code includes a set of complex and simple functions to serve as examples of the possible uses and applications of Microsoft FSO.
' Create the file system object
set oFSO = CreateObject ("Scripting.FileSystemObject")
' *******************************************************************************************
' FilePath - location of the file and its name
' *******************************************************************************************
Function CreateFile (FilePath)
' Variable that will hold the new file object
set NewFile = oFSO.CreateTextFile(FilePath, True)
' *******************************************************************************************
' Check if a specific file exist
' FilePath - Location of the file and its name
' *******************************************************************************************
Function CheckFileExists (FilePath)
CheckFileExists = oFSO.FileExists(FilePath)
' *******************************************************************************************
' FileRef - Reference to the file
' str - Data to be written to the file
*******************************************************************************************
Function WriteToFile (byref FileRef,str)
' *******************************************************************************************
' FileRef - reference to the file
' *******************************************************************************************
Function ReadLineFromFile (byref FileRef)
ReadLineFromFile = FileRef.ReadLine
' *******************************************************************************************
' FileRef - Reference to the file
' *******************************************************************************************
Function CloseFile (byref FileRef)
'******************************************************************************************
' Opens a specified file and returns an object that can be used to
' read from, write to, or append to the file.
' FilePath - Location of the file and its name
' *******************************************************************************************
Function OpenFile (FilePath,mode)
' Open the txt file and return the File object
set OpenFile = oFSO.OpenTextFile(FilePath, mode, True)
' *******************************************************************************************
' FilePathSource - Location of the source file and its name
' FilePathDest - Location of the destination file and its name
' *******************************************************************************************
Sub FileCopy ( FilePathSource,FilePathDest)
' copy source file to destination file
oFSO.CopyFile FilePathSource, FilePathDest
' *******************************************************************************************
' FilePath - Location of the file to be deleted
' *******************************************************************************************
' Copy source file to destination file
' *******************************************************************************************
' FilePath1 - Location of the first file to be compared
' FilePath2 - Location of the second file to be compared
' FilePathDiff - Location of the differences file
' ignoreWhiteSpace - Controls whether or ignore differences in white space characters
' true - Ignore differences in white space
' false - Do not ignore difference in white space
' Return Value: true if files are identical, false otherwise'
' *******************************************************************************************
Function FileCompare (byref FilePath1, byref FilePath2, byref FilePathDiff, ignoreWhiteSpace)
set f1 = OpenFile(FilePath1,1)
set f2 = OpenFile(FilePath2,1)
set f_diff = OpenFile(FilePathDiff,8)
' Count how many lines there are in the first file
' Count how many lines there are in the second file
' Re-open the files to go back to the first line in the files
set f1 = OpenFile(FilePath1,1)
set f2 = OpenFile(FilePath2,1)
' compare the number of lines in the two files.
' assign biggerFile - The file that contain more lines
' assign smallerFile - The file that contain fewer lines
If ( rowCountF1 < rowCountF2) Then
str = "Line" & vbTab & "File1" & vbTab & vbTab & "File2"
' Loop on all the lines in the smaller file
While not smallerFile.AtEndOfStream
' Check if we need to ignore white spaces, if yes, trim the two lines
' If there is a difference between the two lines, write them to the differences file
str = lineNum & vbTab & str1 & vbTab & vbTab & str2
' Loop through the bigger lines, to write its line to the different file
While not biggerFile.AtEndOfStream
str1 = ReadLineFromFile(biggerFile)
str = lineNum & vbTab & "" & vbTab & vbTab & str2
FileCompare = Not differentFiles
' ************** Example of using these functions **********************
FilePath1 = "D:\temp\FSO\txt1.txt"
FilePath2 = "D:\temp\FSO\txt2.txt"
FilePathDiff = "D:\temp\FSO\txt_diff.txt"
d = FileCompare(FilePath1,FilePath2,FilePathDiff,false)
FilePath = "D:\temp\FSO\txt.txt"
set fold = FolderCreate ( "D:\temp\FSO
' = WriteToFile(f,"test line")
Fexist= CheckFileExists(FilePath)
d = WriteToFile(f,"first line")
d = WriteToFile(f,"second line")