Creating a test environment: the easy way

Creating a test environment: the easy way

Testing without proper data can be quite annoying and sometimes even impossible.

I’m working on an application which consist of more than 5 different NSF files. All data are related to each other and linked with an unique ID. Manually copy / paste all the data is not an option, the chance to forget data and have resulting inconsistencies are too big. Another problem: productive data can grow very big (attachments, rich-text fields and so on), simply copy paste the nsf files may result in using too much disc space in the test environment..

The Solution

So i created a lotusscript agent in order to copy the data of multiple databases:

  1. loops through a list of source / target database paths
  2. removes ALL (!) Documents of the target database
  3. copies all Documents from source to target database
  4. removes all attachments during copy process
  5. removes all “Body” fields during copy process
  6. refreshes all views in target database

Usually there is no need for attachments and rich-text content in the test environment, so during the copy process, i remove the attachments and contents of the “Body” field.

WARNING: improper use of this agent can result in loss of data.

Please feel free to adjust the agent for your needs (change field names, leave the attachments, etc).

You find the code here, and also in the NSF file containing the same agent at the bottom of this post. Just copy the agent, start it in designer (be sure no document is open in the notes client of the target db) or server console, lean back or get a cup of coffee while notes is doing the work..

The Code

%REM
	Agent agCopyData
	Created 03.06.2014 by Frédéric Dehédin (www.fdehedin.ch)
	Description: This Agent copies all documents of the dbs specified in the List Variable "dbs". 
	Listtag is the source db, listitem value is the target db. so you can also copy data of mutliple DBs
	WARNING: the agent also removes ALL Attachments and "Body" fields
%END REM
Option Public
Option Declare

Sub Initialize
	On Error GoTo processError
	
	Dim dbs List As String 'specify like: dbs(sourceDbPath) = dbs(targetDbPath)
	
	Dim s As New NotesSession
	Dim db As NotesDatabase
	Set db = s.currentdatabase
	
	dbs("sourcefolder\source_db.nsf") = "targetfolder\target_db.nsf"
	
	ForAll dbToProzess In dbs
		Dim dbSource As New NotesDatabase(db.server, ListTag(dbToProzess))
		If dbSource.isopen Then
			Dim dbTarget As New NotesDatabase(db.server, dbToProzess)
			If dbTarget.isopen Then
				Dim colTarget As NotesDocumentCollection
				Set colTarget = dbTarget.Alldocuments
				Call colTarget.Removeall(true)
				
				Dim colSource As NotesDocumentCollection
				Set colSource = dbSource.Alldocuments
				
				Dim docSource As NotesDocument
				Set docSource = colSource.Getfirstdocument()
				
				Dim i As Long
				Dim count As Long
				count = colSource.count
				For i = 1 To count
					
					Dim docNew As NotesDocument
					Set docNew = docSource.Copytodatabase(dbTarget)
					
					Call removeAttachment(docNew)
					Print "copy " + CStr(i) + " of " + CStr(count) + " documents. "
					Call docNew.Save(True,docSource.Isresponse)
					Set docSource = colSource.getNextDocument(docSource)
				Next
				
				Print "start refreshing views in target database."
				ForAll v In dbTarget.Views
					Call v.refresh()
				End ForAll
				Print "finished refreshing views in target database."
			End If
		End if
	End ForAll
	
	Exit Sub
processError:
	Call raiseError()
	
End Sub


%REM
	Sub removeAttachment
	Description: Comments for Sub
%END REM
Public Sub removeAttachment(doc As notesdocument)
	On Error GoTo processError
	Dim myItem As NotesItem

		Set myItem = doc.GetFirstItem("$File")	
		While Not myItem Is Nothing	
			Call myItem.Remove	
			Set myItem = doc.GetFirstItem("$File")	
		Wend	
		
		Set myItem = doc.GetFirstItem("Body")	
		While Not myItem Is Nothing	
			Call myItem.Remove	
			Set myItem = doc.GetFirstItem("Body")	
		Wend	
	
	Exit Sub
processError:
	Call raiseError()
End Sub


Function RaiseError() 
	Dim thisType As String
	Dim es As String
	'          thisType = Typename(Me)
	' Not a class, use the calling module instead
	If (thisType = "") Then thisType = GetThreadInfo(11)
	es = thisType & "::" & GetThreadInfo(10) & ": "
	If (Err = 0) Then 
		es = es + "Manually raised an error" 
	Else
		es = es +_  
		"Run time error: (" + Trim(Str(Err)) + ") " + _
		Error$ + " at line: "+ Trim(Str(Erl))
	End If
	Print es
End Function

The Download

Download Lotus Notes nsf File - Creating a test environment

Leave a Reply

comment-avatar

*