Inserting and Appending Text with TextSoap

On the surface this seems like a silly, even trivial request, insert a line of text at the top of the file and append a line of text to the bottom of the file. And it is a simple request, until you want to do it in bulk.

Then it becomes a copy/paste nightmare that is woefully inefficient or you get into sed, cat, echo, for .. each loops and some other variants of shell scripting.

What I wanted to do was add code blocks to top and bottom of several Markdown files so they would be seen as code. Groovy code to be specific with the:
”’groovy
”’
While looking for a reliable solution that could be easily implemented, I caught something in TextSoap. It has an Insert Action. It’s an insert Before and After action. When no text is selection, the action is performed on the entire block of text. Since TextSoap has a menu bar button, the action can be performed anywhere.

That lead to this simple solution:textsoap-action

But there is a little more. TextSoap has a Batch File Cleaning function. There you can specify the Cleaner and the files it should act on.

textsoap-batch-cleaning

There is also the TextSoap Palette, which is a floating menu of all the TextSoap filters, including all the Custom Cleaners so it can be repeatedly used with any open application.

textsoap-palette

So what started as shell scripting exercise, turned into a simple two-line insert function within TextSoap that is now available to all applications or could even be run against a series of files. That was pretty handy!

Other articles of interest:

Adding Feature Flags to Test Cases

Feature flags are by no means a new concept, but when used within QA tests, they provide a lot of flexibility and extend the functionality without having to write and maintain multiple test cases.

I've recently added the TimeDuration library to several tests to record how long it takes to perform a "save" action. It's great for me, but I don't want this to run all the time, so it's being wrapped in a feature flag. I start with a simple list of flags at the top of the code like:

boolean timedTest=true

And then later in the code, there is an IF block if (useDataBase==true){ to see if the time should be recored. By default these are off for regression tests. But when I want to use them for functional testing, I change the flag.

Taking that a step further, I've been using feature flags to section off functionality. Let's say we are creating an order. That order needs a list of items. For a regression test, the list needs to be generic enough to apply to multiple scenarios and users.

However, with a feature flag, the list can be be specific for my functional test without having to write a whole new test case or disrupt the existing one. Right now, I am adjusting them at the test level.

Here is a simple example to either read a spreadsheet for generic items or query the database for a specific user and location.

//Read inventory from the database file or xls spreadshseet?
boolean useDataBase=true

if (useDataBase==true){
    WebUI.callTestCase(findTestCase('Populate Custom Inventory List - DB'), [:], FailureHandling.CONTINUE_ON_FAILURE)
}else{
    WebUI.callTestCase(findTestCase('Populate Inventory Items List'), [:], FailureHandling.CONTINUE_ON_FAILURE)
}

Another example would be whether or not to add a custom item to an order. A custom item has specific fields associated with it and isn't used in regression testing.

//add a custom item to the order?
boolean addCustomItem=false
if (addCustomItem==true){
    //Wait for Add Inventory Item button to be visible
    WebUI.waitForElementVisible(findTestObject('btn-Add Custom Item'), 15)

<additional code here>

    //Click to Add Custom Item to Order
    WebUI.click(findTestObject('btn-Save Custom Item'))
}

While these aren't complicated examples, they are the start of consolidating code for functional and regression testing. In the case above, my original test created a certain type of order. With a few small additions, the test is dynamic enough to fill in extra forms when the testing is for my benefit. But with the flags turned off, it acts as a regression test that works for 80-90% of the users in the system. This gives me extra testing capability without having to write and maintain two sets of tests.

Other articles of interest:

Formatting Execution Times with TextSoap

As noted, I have a couple of tests that use the TimeDuration library to time how long certain actions take. For example, the time it takes to Save a large number of items. After running a whole series of test suites, I had a lot of information in the log files. As an experiment, I searched through all the logs and pulled out the “Execution Time:” marker. This gave me multiple instances of how long it took to save that large chunk of data.

I then decided to try out TextSoap to see what sort of formatting I could apply to this text. Could I make some sort of report that showed the really long save times and the longer than average save times?

Simply put, you absolutely can.

Using a bit of RegEx and then applying some formatting, I can call out the really long test that took 3 minutes. Clearly something went totally wrong there.

.*minutes.*

I can then highlight the times that took over 20 seconds.

.*\b[2-9][0-9]\b.*

I can then highlight the times between 10 and 19 seconds as pretty close to problematic.

.*\b[1][0-9]\b.*

In conjunction with these, I can apply text formatting to make a pretty cool little report. From the screenshot, the Minutes time gets red text and gets converted to uppercase.

The 20+ second condition also gets the same treatment.

For 10-19 seconds, get formatted in orange, but no change of case.

So in short order, I was able to use grep to find the Execution Time text and save that to a file. Then TextSoap applies a set of conditional filters and I have a pretty useful report of my automation testing. Now that the “cleaner” is built, this process takes less than 30 seconds to complete.

This could be done several ways and with several different tools. But it seemed like a fun exercise for TextSoap and a way to try out it’s features. And it totally worked.

By the way, my RegEx skills are nigh non-existent. I used regex101.com and comments from Stackoverflow to put these together.

Other articles of interest:

Tools for the QA Engineer

When it comes to web testing, people are familiar with Selenium, Postman, JMeter and others. They’re the staples of heavy testing. But what about when testing has to be done manually. What are the sorts of the tools you bring to the party when you know you’ll have to write everything down by hand and keep a record of what was testing.

I was recently going through the tools I use and came up with this short list of essentials. There is always another tool to add to the belt, but at minimum, I wouldn’t start a project without these.

Here is a list of my personal favorites. Some of the tools have changed over time and might change again before next year is up.

For example, I liked Boostnote, but chose to go with SnippetsLab for the Gists functionality.

I think this is a pretty solid list. I’m sure there is plenty of variation with the actual tool names, but if there is some functionality I’m missing, I’d love to hear about it. I’m always looking for a way to save time and increase efficiency.

TextExpander
– TypeIt4Me
– I save so much time using this tool. It helps to write code fragments as well as fill in forms with standardized info like address, phone, company, etc. Saves a lot of typing. It also handles a lot of my most common snippets.
Note Taking
– Mini Note, MWeb, TextSoap
– Mini Note is for quick text items and a way to share info across Macs.
– MWeb is a great way to take notes, write Markup and create documentation.
– I just added TextSoap for it’s parsing. This could be a big help with filtering big files and log entries.
Document Management
– DevonThink
– DevonThink is my trusted friend for document management and note archives. It holds documents, code, links, and just about anything else you can store on your machine. For Windows, get RightNote.
Clipboard Management
– CopyPaste Pro
– CopyPaste Pro is my current clipboard manager and helps with repetitive pasting operations.
Task Management/Test Management
– 2Do
-My standard way of tracking tasks and creating test case items
Code Development
– Coderunner
– Very handy text editor. A great way to run shell commands. Helpful for writing sample code.
Screen Capture
– SnagIt
– It’s capabilities shouldn’t need any introduction. 🙂
File Sharing/Download
– FileZilla
– FTP is alive and well. This is the tool for the job.
Snippet Management
– SnippetsLab, DevonThink
Window Management
– Fiplab Window Manager
– It is so beneficial to be able to resize windows, split screen, and order your work environment.
– Magnet is a great alternative. For Windows, you need DisplayFusion.

Other articles of interest:

Programmatic Database query with Katalon

As mentioned previously, making dynamic database queries was a big goal for this year. Katalon makes this quite easy with a UI to set up the connection and a straightforward way of connecting to the data itself.

To start the process, select Data Files, New Test Data and select Database as the source.
Taking the configuration string from before, we connect to the database using this screen and provide the default query. This creates a default table of data that Katalon will work with when executing tests.

Within our code, we use the TesData object to get at our database source.
TestData inventoryDB = findTestData('Data Files/database object name')

We can now get the number of rows in the database, the names of the columns and read data from each column as needed. We need to reference each column with an index number rather than it’s name. Even though Katalon displays "item_number" as the column title, internally that is column 1.

However, we can still use item_number by getting a list of the columns and finding it’s index. I am adding 1 to the index since the List starts at 0 and 0 isn’t a valid column.

From there, we read information from the database using the getValue statement:
inventoryData=inventoryDB.getValue(columnIndex, loop)

From this very simple example we can get the counts of rows and column, then read the correct item from the list.

int loop=1, columnIndex=1, rowCount=1
String inventoryData=''
//Connect to Database Object in Data Files
TestData inventoryDB = findTestData('Data Files/Inventory Items Query')
rowCount=inventoryDB.getRowNumbers() //Row count for the number of results returned
List columnNames=inventoryDB.getColumnNames() //A List of the column names
columnIndex=columnNames.indexOf("item_number")+1 //Get the index of the column name we want

for (loop = 1; loop <=rowCount; loop++) {
    //Read the column data from the database and assign to a List
    inventoryData=inventoryDB.getValue(columnIndex, loop) //Read data directly from the database query
    GlobalVariable.inventorySKU[loop]=inventoryData
}

Other articles of interest:

Recent Comments