25
Automation Anywhere Bot Development Best Practices Document Information Version: 2.2 Created by: Automation Anywhere Professional Services Team Last Modified on: 12/12/2018

Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Automation Anywhere

Bot Development Best Practices

Document Information

Version: 2.2

Created by: Automation Anywhere Professional Services Team

Last Modified on: 12/12/2018

Page 2: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Contents

Purpose ........................................................................................................................................................... 3

Don’t Repeat Yourself Principle (DRY) ............................................................................................................ 3

Rule of Three ................................................................................................................................................... 5

Single Responsibility Principle ........................................................................................................................ 5

Decoupling and Loose Coupling ...................................................................................................................... 6

Design for Testability ...................................................................................................................................... 6

Commenting ................................................................................................................................................... 7

Naming Conventions ....................................................................................................................................... 8

Sessions ........................................................................................................................................................... 9

Folder Structure .............................................................................................................................................. 9

Variable Operation ........................................................................................................................................10

Build Portable Bots .......................................................................................................................................12

Go wild with Wildcard (*) .............................................................................................................................13

Object Cloning ...............................................................................................................................................13

Error Handling ...............................................................................................................................................14

Logging ..........................................................................................................................................................18

VB Script ........................................................................................................................................................22

Config (Configuration) File ............................................................................................................................22

Bot Dependencies .........................................................................................................................................24

Maintaining Windows ...................................................................................................................................24

Automation Friendly Input Formats .............................................................................................................25

Page 3: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Purpose

The purpose of this document is to provide guidelines, standards and best practices for developing

Bots/Automations using Automation Anywhere. Not every person developing an automation:

• is aware that a task (or any code set) is generally read several times more than it is changed

• is aware of some of the pitfalls of certain constructions in automation development

• is aware of the impact of using (or neglecting to use) certain approach on aspects like

maintainability and performance

• knows that not every person developing an automation can understand an automation as well as

the original developer

Following standards and best practices will help you create clean, easier to read, easier to maintain, stable

automations.

Don’t Repeat Yourself Principle (DRY)

The Don’t Repeat Yourself Principle is a principle commonly found in software engineering. The aim of this

principle is to reduce the repetition of information. In the context of automation, it refers to creating a set

of commands or bits of logic that are repeated throughout a single task.

For example, suppose an automation has the need to print a notepad document as a PDF file. The task

might look like the following:

FIGURE 1

In this particular automation, there is a need to print a file as a PDF document three times. The temptation

would be to simply copy and paste these nine lines into the three places where they are needed. It’s fast

and simple and helps resolve the immediate goal – getting this automation finished quickly. However,

copying and pasting these lines 3 times is short-sighted.

Consider for example on the development machine the PDF print driver is called “Pdf995”. When the

automation is moved to a production machine it is discovered that the PDF print driver on that machine is

not called “Pdf995”, but rather “CutePDF”. Now the entire automation task must be opened and edited.

Page 4: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

In addition, there are three places to find this code, and because this is copied and pasted the automation

is now 27 lines longer than it would have been. Long tasks are more difficult to edit and takes more time.

Not only that, a task that was tested and verified to be bug-free and production ready has now been edited.

Since it has been edited, it is no longer production ready because it has been changed and should now be

re-tested.

By saving an extra minute of time copying and pasting these nine lines in three different places, 30 minutes

to an hour of maintenance time have now been added because the task must be edited and it’s longer than

it normally would have been. If a new developer has been tasked with making changes and they are

unfamiliar with the automation, they must now do more analysis to determine all of the places that need

the change. If the task is short, that’s not so bad, but if it’s long, it’s much more time consuming.

Of course, in this example using variables could alleviate some of these issues. But now yet another variable

must be added and maintained, making the automation more cluttered. And there’s always the possibility

that the issue can’t be resolved by simply using a variable.

So, what’s the solution? A sub-task, that is called by the task needing this service performed. By placing

these commands into a task that is called by a parent task, we realize a number of benefits:

1) the main task is now 27 lines shorter

2) when it moves to production, only 9 lines have to be located, analyzed and edited and they live in

a single task, making the automation much easier to maintain

3) these lines can be called by any number of tasks, even in other automations

Sub-tasks can be referred to as a “helper task” or “utility task”, since their only purpose is to help the calling

task. Figure 2 is an example of what the helper task for the above example might look like:

FIGURE 2

If any changes are required to this specific set of commands, only this helper task will need to be edited,

and only this helper task will need to be retested. For example, to address the concern of possibility of

Printer Name Change between various Environments or Machines, the “Pdf995 Save As” Window Title

could be changed to “* Save As” using Wildcard (*) to accommodate all possible printer names.

Page 5: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Tip: Remember that Excel sessions, CSV/text file sessions and browser sessions (web recorder) cannot be

shared across tasks. So sub-tasks must be included in such a way as they do not break these sessions.

Rule of Three

Keeping in mind the Don’t Repeat Yourself Principle, The Rule of Three is a great way to prevent introducing

repeating code or commands. This rule is typically only applied to a small number of commands, or even

single commands. For example, if a task calls a sub-task, and then calls it again when it fails, it is acceptable

to have two call sites; however, if it is to be called five times before giving up, all of the calls should be

replaced with loop containing a single call.

Tip: Sub-tasks should be small and focused (have only a single responsibility or only a few responsibilities).

Single Responsibility Principle

In object-oriented programming, the single responsibility principle states that every class should have

responsibility over a single part of the functionality provided by the software, and that responsibility should

be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.

This principle directly applies to automation development as well.

Now imagine a single automation task that is 2000 lines long. This task is far too long and should be split

into several sub-tasks. The automation developer decides to put several of the repeated tasks into another

sub-task. Consider for example he or she picks three repeated sections and puts them in a sub-task. This

new helper task now handles printing a PDF, but also handles saving a file to a specific folder, and in

addition to that it also handles moving a file from one folder to another. The developer manages which

part is called by passing an action variable.

The above example would break the Single Responsibility Principle. The developer has reduced the number

of lines in the master task, which is good, but has now a sub-task that is far too big. Additionally, if any one

of those responsibilities (printing a PDF, moving a file or saving a file) need to be modified, the entire helper

task must be modified. This creates the possibility for introducing a bug in task that would not have

otherwise been affected.

The proper approach would be to create three sub-tasks, each having their own responsibility –

1. Print to a PDF

2. Move the file

3. Save the file

Page 6: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Decoupling and Loose Coupling

When possible, sub-tasks should not have a dependency on the calling task. In automation this is often

unavoidable. However, developing with this in mind can improve the overall architecture and

maintainability of an automation.

Using the login sub-task as an example, if the login task can only be called by one single master task, then

it is tightly coupled to that master task. If the login sub-task is designed in such a way that the URL of the

page it uses has to be set by the calling task, then it cannot run by itself. It cannot be unit-tested alone, and

other tasks cannot call it without knowing the URL of the login page before calling it. If the calling task must

provide the login page URL to the login sub-task, then all tasks that use the login sub-task are more tightly

coupled to that login sub-task. And if the URL changes, more than one task must be changed.

However, if the login sub-task contains all of the information it needs to login to the web application,

including the URL, then it is a truly stand-alone sub-task. It can be unit-tested, and it can be called by any

other task without the need to be provided the URL. It is then “decoupled” from other tasks and is much

more maintainable. This needs to be evaluated on case by case basis, since it may not always be possible

to decouple.

Design for Testability

If automations are developed using the above principles, the result will be many smaller tasks, many being

reusable. These smaller tasks can then be tested alone, in a unit-test fashion.

For example, take an automation that always starts with a login to a web-based application. The login step

should be in a separate sub-task. Using this approach, if anything changes with the login UI, only the login

task has to be modified. If several other tasks are using the login step, none of those tasks will need to be

modified or re-tested if the login UI changes. If the task is created using the Single Responsibility Principle,

it only performs one function – logging in to the application. Additionally, if the task is designed to be

loosely coupled, it doesn’t need to know anything about the master task calling it. The URL, user name and

password can be put into the automation for testing purposes, and then that task can be tested

independently. This is far more efficient than modifying a single large task or set of tasks if something

changes in a smaller unit.

This approach may not be possible in all cases, but when possible, this can make an automation much

easier to maintain and deploy.

Page 7: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Commenting

Most automations require changes after they are placed into production. Sometimes those changes can

be frequent, depending on the type and scope of the automation. The difference between a change being

a relatively straight-forward task and a complete nightmare is determined by two things: how cleanly the

automation was architected, and how well it is documented and commented. Good commenting can mean

a difference of hours during a maintenance cycle.

General rules:

• Box important sections with repeating slashes, asterisks or equal signs:

• Use one-line comments to explain assumptions, known issues and logic insights, or mark automation segments:

• Make comments meaningful:

• When automating User Interfaces (UI) use Comments to denote where significant activities are taking place, so that Developer/Reader doesn’t have to guess what UI element is getting affected.

• Include comments using Task-List keyword flags to allow comment-filtering. Example:

// TODO: Place database command here

// UNDONE: Removed keystroke command due to errors here

• Never leave disabled Task lines in the final Production version. Always delete disabled task lines before Uploading your Tasks.

• Try to focus comments on the why and what of a command block and not the how. Try to help the reader understand why you chose a certain solution or approach and what you are trying to achieve. If applicable, also mention that you chose an alternative solution because you ran into a problem with the obvious solution.

Page 8: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Naming Conventions

Use camelCasing for Variables and PascalCasing for Task names:

• Pascal Case is the practice of writing compound words or phrases such that each word or

abbreviation begins with a capital letter (e.g. PrintUtility)

• Camel Case is the same, but always begins with a lower letter (e.g. backgroundColor).

Keep the variable and task names short and concise. Consider limiting use of unnecessary characters such

as underscores and blank spaces (in Task Names). Avoid single character variable names. Never use “i” or

“x” for example. A reader should always be able to look at a variable name and gain some clue about what

it is for, e.g. vEmployeeFirstName or vSocialSecurityNumber.

Use meaningful prefix to help identify Type of variable, as mentioned in the table below:

Prefix Data Type Example

v Value vCustName

a Array aCustDetails

l List lCustNames

r Random rNewPassword

Name Flags with Is, Has, Can, Allows or Supports, like vIsAvailable, vIsNotAvailable, vHasBeenUpdated.

Name Tasks with a noun, noun phrase or adjective. Try to add a prefix or suffix like “Main” in the

main/parent deployable Task’s name. Similarly, for Tasks which are always called by other Tasks, try to use

a suffix such as “Utility” or “Helper”, for example FileSaveHelper.atmx.

While naming variables whose values will be passed between the Main Task and Sub-Task, keep them

same. This way you will be able to utilize “Quick Map” feature within Run Task command to map all

variables at once by just one click.

Never initialize your variables within Variable Manager, except where you are defining an Array variable

that is going to contain constant values (aka Look-up Table). For readability, always initialize variables in

Task Actions List with help of Variable Operation or other appropriate commands.

Avoid using options within Add Variable dialog to initialize variables using external data sources, since you

do not get an opportunity to handle any exceptions.

Page 9: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Sessions

Session is nothing but a Reference Point to data and is part of Commands which accesses external data.

For example, Open Spreadsheet, SQL Query, Start XML Session, etc. Once a Session Name is defined in such

Command, for example Open Spreadsheet, pointing to an external data set, then the same data set can be

accessed within subsequent Commands, for example Get Cells, just by specifying the same Session name.

Therefore, having unique and meaningful Session name is essential. DO NOT use “Default” as Session name.

You may also use Variable in place of Session Name, which will further reduce possibility of making typos

while typing Session names in Commands.

Make sure you close all the Sessions that you open, to release lock/hold on external data source, such as

Excel File, Database, etc. Also, note that you cannot have two Sessions with the same name open

simultaneously, even across different Bots.

Folder Structure

Files that the Bot/Task uses, e.g. config, input, output, logs, etc., should be grouped in meaningful and

segregated Folders. This should be further separated for different Environments. You don’t want to mix up

DEV environment Output files and Logs with PROD environment. Access to specific UAT and PROD folders,

such as Config, can be restricted only to Admins and respective Environment’s Bot/Service Accounts, to

prevent sensitive data/values from getting exposed to Developers or unintended users. An example of

such folder structure is shown in the figure below:

Page 10: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

It is recommended to host this folder structure on a NAS Network Shared Folder, instead of the local drive

of Bot Runner machine. Because it is very unlikely that the Bot Developers/Support Team will have access

to PROD Bot Runner machines, for security reasons.

You could have a variable called vEnvironment in you Tasks, which will at runtime receive value of the

Environment in which the Task is currently running, e.g. “DEV”, “UAT”, “PRD”. This value could be returned

by a Library Task, e.g. GlobalSettings.atmx, which will look at the $AAControlRoom$ System Variable, which

has unique Control Room URL for every environment, and then return appropriate value accordingly to the

calling Task, e.g. “DEV”, “UAT”, “PRD”. Subsequently, as long as variable vEnvironment is used to build Path

of your Folder Structure, your Task will automatically do the switching between Environment appropriate

folders at runtime.

Variable Operation

Variable Operation command will attempt to perform arithmetic operation if it finds given value containing

only valid numbers and arithmetic operators such as +, -, /, %, *. For example, to set Today’s Date in a

variable you may specify value as 08/21/2018. But, since the given value contains only valid numbers and

Page 11: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

division operator (/), the Variable Operation command will perform Division and result of that Division,

which is 0.000188777195714758, is the value that will be assigned to the Variable instead of the Date.

Following table shows few more examples:

Variable

vA

Variable

vB

Value specified in Variable

Operation

Result

5 34 $vA$ + $vB$ 39

-5 34.8 $vA$ + $vB$ 29.8

5.2 34.8 $vA$ + $vB$ 40

5.2.8 34.8 $vA$ + $vB$ 5.2.8 + 34.8

5.2 Apples $vA$ + $vB$ 5.2 + Apples

Uncle Sam My great $vA$ $vB$ My great Uncle Sam

As a workaround, Trim String Operation command can be used for such scenarios. You can put your value

containing valid numbers and arithmetic operators (such as Date) in Source String and assign output to

desired variable as shown in the screenshot below.

Page 12: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Following Arithmetic Operators are recognized by Variable Operation command:

Operator Purpose

+ Addition

- Subtraction

* Multiplication

/ Division

% Modulus (divides two numbers and returns the remainder)

( ) The Operations are evaluated from left to right in general. Operations inside

Parentheses takes first priority in the order.

Build Portable Bots

Any time you use Run Task command to run a Sub-Task, the path to Sub-Task’s ATMX file gets hardcoded

by default. This path includes Bot Developer’s User Profile Folder, which will not be available in Bot Runner

machines of subsequent Environments, such as UAT and PROD. Thus, the best practice is to utilize

$AAApplicationPath$ system variable to build a Portable path. For example:

C:\Users\BotCreatorUser\Documents\Automation Anywhere Files\Automation Anywhere\My

Tasks\LIBRARY\ParseStringForDate.atmx

is changed to

$AAApplicationPath$\Automation Anywhere\My Tasks\LIBRARY\ParseStringForDate.atmx

On the other hand, for Paths to files such as Output and Logs used in Log To File command as an example,

use variable vEnvironment whose value will switch automatically at runtime depending on the

environment in which the Task is executing, e.g. “DEV”, “UAT”, “PRD”. This will help switch between

environment appropriate folder paths at run time and will make your Task portable.

Following figure shows preferable commands for low to high portability. The high portability commands

mostly do not depend on Bot Runner machine screen’s resolution or an Object’s coordinates. Hence, are

less susceptible to break once ported to an unidentical Bot Runner machine configuration.

Page 13: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Go wild with Wildcard (*)

Asterisk (*) is the Wildcard character in Automation Anywhere world. To give you an example, for “Select

Window” property of various commands such as Close Window, If Window Exists, Insert Keystrokes, Object

Cloning, to name a few, you can specify one or multiple wildcards (*) in the beginning, middle or end of

the Window Title value.

For example, if you want to perform an operation if any window has the word 'Microsoft' in its title, then

you can use wildcards to indicate any string before or after 'Microsoft' by updating that value to

'*Microsoft*'. Automation Anywhere Client will first search for the exact window title ('Microsoft'), and if

it does not find it, it will look for windows with the word Microsoft anywhere in the title.

You can use wildcards as well as variables within Object Cloning Property Values too. This way you can

make the same Object Cloning command work for different objects in different scenarios. For example,

iterating over Rows in a HTML Table, one at a time, with the same Object Cloning command.

Object Cloning

For Object Search Criteria, always choose properties with static values. For example – Name, Class, Type,

HTML ID, DOMXPath. Make sure to exclude properties with dynamic/changing values from Search Criteria,

Page 14: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

such as HTML Href, Value, etc. Do not take this as a thumb rule. At times, you may see that the Value

property contains static value all the time. In such case you may include that property to Search Criteria.

All Objects will provide a property called Path, which could be non-static in some situations. You will need

to observe Bot executions and make a judgement call on whether to include or exclude it. General

recommendation is to exclude Path property, pretty much all the time. Include it only if no other property

has static value to uniquely identify that Object.

Web Application Objects have a property called DOMXPath, in addition to Path. It is highly recommended

to include DOMXPath property in the Search Criteria, since its value is almost always unique and static. In

situations where you need to interact with one object in a collection, for example a Row in a HTML Table,

you will need to identify the part of DOMXPath value that is varying from one object to another (typically

a number starting from 1) and replace it with a variable. Now, you can iterate over each object in the

collection by simply incrementing value of that variable by 1 within a Loop.

In situations where you experience that the “Click” Action is not working as expected, switch to “Left Click”

action and vice versa.

When using “Set Text” Action, typically available for Textbox objects, by default the Delay is 0 milliseconds

(ms). The Object Cloning command will Set the “Value” property of cloned object to user provided value.

This should work in most cases. However, if you experience that this is not working as expected, then

introduce some Delay, such as 250 milliseconds (ms). Then, the Object Cloning command will send

Keystrokes to the cloned object. This delay will be used between each Keystroke.

You can use wildcards (*) as well as variables within Object Cloning Property Values. This way you can make

the same Object Cloning command work for different objects in different scenarios.

Error Handling

Automating applications, especially browser-based applications, can be a moving target at times. If a web

page changes for example, it will often break the automation. Or most commonly, if a Page or Object

doesn’t appear when the automation expects, it can cause an error. The key to a successful automation is

predicting and handling expected events (a “Save As” dialog not appearing within a specific time frame for

example), and unexpected events (a file not found message for example). You are not limited to one Error

Handling Command in a Task. You can and should have multiple and nested Error Handling Commands, as

appropriate.

Never assume conditions will always be as you expect them to be. It is essential to make use of Error

Handling command in all your Tasks. It is VERY IMPORTANT to make sure that your Task quits gracefully,

even in case of an exception, by closing all the Application Windows that it opened during execution. So

that the subsequent Task that runs on the same machine will not be interrupted by the Windows left open

by previous Task’s run. The “Continue” Action in Error Handling Command lets you proceed after the End

Error Handling line (this is where Error Handling Command’s scope ends). That is where you can add

Page 15: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Commands, such as Close Window, to perform necessary Clean-up, meaning closing Windows that were

opened, leaving a clean environment for the subsequent Task’s execution.

Use this command to not only Log errors and Send Email Notification, but to also provide a means to

recover from an error. For example, design your Task to maintain a Runtime Transaction Log in the form of

a CSV file, having an additional column specifically to mark Completion for each Transaction. Now, if an

exception occurs in the middle of a set of Transactions, the Error Handling Command will catch it, take

necessary actions and then gracefully quit the Task as described above. Once you fix that exception and

run that Task again, it will refer to the Runtime Transaction Log CSV file and can pick up after the last

Completed Transaction leaving previously completed Transaction untouched.

Below are some Best Practices for each Error Handling Option:

Page 16: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Take Snapshot

Example Value: $vLogsFolder$\ErrorImg_$Year$_$Month$_$Day$_$Hour$_$Minute$_$Second$.png

Have a variable in your Tasks called $vLogFolder$, which will contain complete path to the Log Folder. As

you can see in the example value above, System Variables have been used in the Error Image File name to

make it Dynamic, to help avoid accidental overwriting and thus loss of pre-existing snapshots.

Page 17: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Run Task

Example Value: $AAApplicationPath$\Automation Anywhere\My Tasks\Library\CleanUp.atmx

Ensure that you are using $AAApplicationPath$ System Variable in the path of ATMX file to run, to make it

“User Profile Folder” independent. Do your due diligence before using this Option, because, at times you

may not want to perform Clean-Up as part of Error Handling Command placed within a Sub-Task/Helper-

Task. You may want to leave that for your Main Task to do.

Log Data into File

Example Value: $vLogsFolder$\ErrorLog_$Year$_$Month$_$Day$.csv

Have a variable in your Tasks called $vLogFolder$, which will contain complete path to the Log Folder. As

you can see in the example value above, System Variables have been used in the Error Log File name to

make it Dynamic, to help avoid accidental overwriting and thus loss of log data. This will ensure that at

most only one Log File will be created for any day. Using CSV extension/format for Log Files is

recommended, since these files can be opened in Excel Application and you can take benefit of Excel

features such as Sorting, Filtering, Find, etc. Each field text simply needs to be delimited by Comma, to

create a valid and structured CSV log file. It is recommended to log values of following System Variables at

the minimum, which will provide you most important information on the Error that occurred:

$Date$,$Machine$,$System(USERNAME)$,$AATaskName$,$Error Line Number$,"$Error Description$".

You may even add your own Custom Text or User Defined Variables as needed. Just separate each field

with Commas. Any variable/text which may contain a comma (,), for example $Error Description$, must be

qualified with a pair of double-quotes (“ ”) to avoid splitting of that value into two Separate columns in

your CSV file.

Send Email

As shown in the Error Handling Example Screenshot above, use Variables for “Email” and “From” fields

instead of inputting actual Email Addresses. This way, if an Email Address needs to be changed (to make it

appropriate for different Environment or because the person was replaced) then it can be changed only in

one place where the Variable is initialized. It is recommended to maintain input and changing values, such

as Email Address in this case, in a Config file and have the Main Task read from Config file to initialize

corresponding Variables. “Attach Snapshot” option attaches an Image file to the Email which shows state

of Desktop Screen at the time of Error. “Attach Variable” option attaches a Text file to the Email which lists

all the Variables with their values at the time of Error.

Note: If the Task has Variables which will be assigned PII (Personally identifiable information) Data, such

as Social Security Number, Date of Birth, etc. or the Task interacts with User Interfaces showing such

Data, then DO NOT select “Attach Snapshot” and/or “Attach Variable” options to adhere to Data Privacy

policies.

Variable Assignment

Example Value: $vIsError$ = 1

This Option lets you set a Flag/Variable which can help convey to the subsequent Actions, following End

Error Handing line, that an Error had occurred and was handled. This is also an easy way for a Child Task to

Page 18: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

communicate to the Parent/Calling Task that it handled an Error, just by mapping Variable (e.g. $vIsError$)

and setting/flagging it using Variable Assignment Option within Error Handling Command.

$Error Line Number$ and $Error Description$ System Variables hold their values even past the End Error

Handling line. If you would like to reset their value for some reason, then you can use Variable Operation

command as shown below:

Logging

One phrase that will be repeated throughout this section will be this: Logs should be easy to read and easy

to parse. There are two receivers for log files, humans and machines. When humans are the receiver, they

may be a developer looking for information in order to debug, analyse performance, or look for errors.

They may also be an analyst, looking for audit information or performance information. In either case, logs

should be easy to look at and understand, and they should be easy to parse with a tool or import into Excel.

What follows is a set of standards to ensure logging is properly executed.

There are about five different types of messages that could be logged. Depending on the type, they may

go into separate log files. For example, informational messages should go into the primary process log,

where as an error message would into both the process log and an error log. Debugging information should

go into a debug log. It is recommended to use CSV as a format for Log files, with Date-Time Stamp value

for Column 1. These files can be opened in Excel Application and you can take benefit of features such as

Sorting, Filtering, Find, etc. Also, logs aggregation tools such as Slunk (if integrated) will also benefit from

receiving log data in structured format.

Use Log To File command built into Automation Anywhere. A good format to use is Date-Time stamp,

machine name, user name, name of the task, and the message. Optionally, you could have a column for

Page 19: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

logging level (Debug/Error/Info/Warning) if you are PERMITTED to have only one log file. All of these values

should be comma (,) delimited, to make a valid CSV format log file for easy importing or parsing. Any

variable/text which may contain a comma (,), for example $Error Description$, must be qualified with a

pair of double-quotes (“ ”) to avoid breaking that value into two Separate columns in your CSV file.

Types of Logs

Audit/Process/Runtime/Informational Log (Recommended) – The Process log is meant to be an

informational log. It can be used for monitoring normal operation of a task, but more importantly, it can

be used for auditing. Use the process log for an audit trail can be an excellent method for determining if a

business process was completed properly. Some of the events and milestones that can be captured

includes:

• Main Process start time & end time

• Sub-process start time & end time

• Target Application launch and login success/failure

• Data/File/Folder/etc. validation failure

• Number of Transactions received in Input File

• Number of Transactions Processed without issues

• Number of Transactions failed validation or caused issue

Example Format of Audit Log CSV File:

Date Time Machine Bot Username TaskName Description

Following System Variables can be used for some of the Column Values: $Date$, $Machine$,

$System(USERNAME)$, $AATaskName$

Error Log (Recommended) – The error log is for detailed error messages. When an error occurs in a task,

notification that an error occurred should go into the process log. Detailed information about the error

should go into the error log. Logging errors is one of the most important roles of logging. If an error is

logged from within an AA Error Handling Command, the Error Line number and Error Description coming

from AA should be included in the message/description.

Example Format of Error Log CSV File:

Date Time Machine Bot Username TaskName Error Line Number Error Description

Following System Variables can be used: $Date$, $Machine$, $System(USERNAME)$, $AATaskName$,

$Error Line Number$, $Error Description$

Debug Log - Debugging information should go into its own log file and should be turned off when in

Production mode. An vIsProductionMode variable could be used to turn these statements off when the

automation is moved to Production.

Page 20: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Performance Log - Performance logging can either go into the process/informational log. In some cases, it

may be desirable to have it in its own log file.

Types of Messages

ERROR – something terribly wrong had happened, that must be investigated immediately. The task cannot

perform its function properly here. For example: database unavailable, mission critical use case cannot be

continued, file is busy and cannot be opened.

WARN – the task might be continued but take extra caution. For example: “Task is running in development

mode”. The task can continue to operate, but the message should always be justified and examined.

INFO – Important business process has finished. In ideal world, and administrator or user should be able

to understand INFO messages and quickly find out what the application is doing. For example, if an

application is all about booking airplane tickets, there should be only one INFO statement per each ticket

saying “[Who] booked ticket from [Where] to [Where]”. Other definition of INFO message: each action that

changes the state of the application significantly (database update, external system request).

DEBUG – Developers’ stuff. Any information that is helpful in debugging an automation and should not go

into the process log. A vIsProductionMode variable should be used to turn these statements off when the

automation is moved to Production.

PERFORMANCE – Performance logging can either go into the process/informational log or it can go into

the performance log, if a separate performance log has been created. Performance should track how long

it takes to perform specific steps, but too much granularity should be avoided. In most cases, performance

logging should be limited to an overall business process. For example, how long it took to complete an

order, or how long it took to process an invoice.

Know What You Are logging

Every time you issue a logging statement, take a moment and have a look at what exactly will land in your

log file. Read your logs afterwards and spot malformed sentences.

Know Who is Reading Your Log

Logs will be imported by the customer. Logs should be easy to read and easy to parse. Users, customers

and automation developers will be looking at logs to:

• determine if a process completed successfully

• if a process didn’t complete, they’ll be looking for information as to why

• determine if the automation is performing as expected

• interactively tailing the logs

• parsing the logs with a tool or importing the logs into Excel to gather and analyse metrics

• importing the logs into a database if necessary

Page 21: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Be Concise and Descriptive

Each logging statement should contain both data and description. Consider the following examples:

FIGURE 5

FIGURE 6

In Figure 5, two lines are used to communicate one set of information. All of the information should be on

one line, and in one pass to the log command. Was it so hard to include the actual message type, message

id, etc. in the warning string? I know something went wrong, but what? What was the context? Be detailed,

don’t make the reader wonder what is going on.

Avoid the “Magic Log”

Another anti-pattern is the “magic-log”. If a log file is long, or has grown to a large size, it may be tempting

to insert characters or strings that make things easier to find certain lines. They’re meaningful to the

developer, but completely meaningless to anyone else. This is why they’re called “magic”. An example

would be “Message with XYZ id received”.

If this approach is used, you’ll end up with a process log file that looks like a random sequence of characters.

Instead, a log file should be readable, clean and descriptive. Don’t use magic numbers, log values, numbers,

ids and include their context. Show the data being processed and show its meaning. Show what the

automation is actually doing. Good logs can serve as a great documentation of the automation itself.

Avoid Side Effects

Performance is the primary concern with logging. Normal logging commands themselves are not costly in

terms of performance. However, consideration should be made for excessive logging (inside of a small loop

with many iterations for example).

Log Sub-Task Variables (Log Level - DEBUG)

When passing variables back and forth to sub-tasks, adding debugging log statements is recommended.

These should be used to see the values of variables when they enter the sub-task, and what they have been

set to when being passed back (where relevant). An vIsProductionMode variable should be used to turn

these statements off when the automation is moved to production.

Consider Size, Rotating and Dozing

Always consider how large a log file will become. By nature, log files generally become quite large in a short

period of time. Additional code should be considered for checking the current date, and if the day has

Page 22: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

changed, creating a new log. This way a new log file is created for each day, and older log files can be

compressed and archived (dozing). A good practise is to use System Variables within File Name, for

example, \ErrorLog_$Year$_$Month$_$Day$.csv. This way no one log file will grow into a huge

unmanageable size. You will have max one file for any day and the Date in File Name will help you identify

and review the intended block of log data.

Interfacing with External Systems

If an automation will be interfacing with other systems i.e. Metabots, APIs, REST or SOAP calls, be sure to

log those calls, and if appropriate their responses.

Note: NEVER log Passwords or any PII (Personally identifiable information) Data, such as Social Security

Number, Date of Birth, etc. in any type of Log File.

VB Script

Automation Anywhere has the ability to execute VB script. It is recommended to limit the use of VB script

to situations where there are simply no other choices. The reasons are:

• VB script is difficult to maintain and work with. Specially if you are creating/modifying them in

Notepad.

• VB script file’s execution is usually prohibited by IT policies on PCs. Also, it is not easy to share

them since they are usually blocked by Email Servers.

• Proper VBA based Error Handling must be implemented within VB Script, otherwise in case of an

error within VB Script it will display a Message Box which will require a human to click OK on. Until

that happens, the control will not come back to AAPlayer.exe and the Bot execution cannot

proceed further. Note: Look up VBA Command - “On Error Resume Next”.

Config (Configuration) File

Always separate your initial Variable values from your task. This means do not set/hardcode Variable values

in the Task directly. Most likely, you will need to change all or some of these values when you run the Task

in different environments, like DEV, UAT and PROD. Use a Config file to store such values. Read the Config

file at run time and set corresponding variables at the beginning of the Main/Parent Task. This way your

Task code doesn’t need to change from one environment to other, only the values within Config file will

Page 23: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

change. The objective is to allow as many aspects of the process to be configured as can be reasonably

achieved. Examples of such values would be:

• URLs to access Web applications being used in automation

• Email Address(es) to be notified in the case of exceptions

• Path to Output folder

• Static values being used in calculation or formula

Only non-sensitive information should be stored in Config files. For any sensitive information such as

Application or Database Login Credentials you should use Control Room Credential Lockers. Best practice

is to use XML format for Config files, it is also the industry standard. Built-in AA XML Commands can be

used to easily read values from such files and assign to variables.

You may choose to host your Config File in “My Docs” Repository folder and declare the file as your Bot

Dependency. Doing so will ensure that it will be deployed to Bot Runner machine along with your Bot’s

ATMX file(s). Following is an example Config File format for this option:

Example Location of Config file: $AAApplicationPath$\Automation Anywhere\My

Docs\Billing\BillProcess\Config.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<configuration>

<DEV>

<AppURL>https://PeoplesoftDevUrl</AppURL>

<OutputFolder>\\network-share\rpa\BillProcess\DEV\output </OutputFolder>

</DEV>

<UAT>

<AppURL>https://PeoplesoftUatUrl</AppURL>

<OutputFolder>\\network-share\rpa\BillProcess\UAT\output </OutputFolder>

</UAT>

<PRD>

<AppURL>https://PeoplesoftPrdUrl</AppURL>

<OutputFolder>\\network-share\rpa\BillProcess\PRD\output </OutputFolder>

</PRD>

</configuration>

In cases where it is not acceptable to host it in AA Repository, you may host your Config File on the Network

Shared Folder along with other files that the Bot reads from or writes to, such as Input, Logs, Output files.

Therefore, you should have separate Config file for each Environment, stored in environment appropriate

folder branch. To prevent sensitive data/values from getting exposed to Developers or unintended users,

Access to UAT and PROD Config folders can be restricted only to Admins and UAT/PROD Bot Runner Service

Accounts. Following is an example Config File format for this option:

Example Location of Config file: \\network-share\rpa\BillProcess\$vEnvironment$\Config\Config.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<configuration>

<AppURL>https://PeoplesoftDevUrl</AppURL>

Page 24: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

<OutputFolder>\\network-share\rpa\BillProcess\DEV\output </OutputFolder>

</configuration>

Bot Dependencies

Bot Dependencies is a Pane available beside Variable Manager Pane in Task Editor and is a feature

introduced in v10 SP2. Generally, when a Sub-Task is called using Run Task command or a Metabot Logic

is used within your Task, Control Room automatically identifies those Sub-Task atmx files and Metabot

mbot files as dependencies of your Task. This information helps Control Room with building a Package

including your Bot’s atmx file along with all other dependency files that it depends on, before this Package

is deployed to the Bot Runner machine for execution.

Now, let’s suppose your Task depends on a VB Script (.vbs file) and an Excel Template (.xlsx file) for its

execution, and uses Run Script and Open Spreadsheet commands respectively for those files, the Control

Room is not capable of automatically identifying that your Task depends on these files. Because, typically

variables are used within Commands to provide Path of such files. In such cases, you can manually declare

that these files are your Bot’s dependencies by adding them to Bot Dependencies pane. You are limited to

choosing dependency files from My Tasks, My Docs and My Scripts folders. If you attempt to choose a file

outside these folders, then you will get an alert as shown below. This restriction ensures that Control Room

will have access to dependency files while packaging your Bot for deployment.

Also, note that the Path of these dependency files specified within Commands must use

$AAApplicationPath$ system variable to make your Task portable.

Maintaining Windows

Always close all Windows that your task opens before terminating the task. Best practice is to attempt to

close all possible Windows that are open at the beginning of your task, so that it starts off uninterrupted

with a clean slate.

It is a good idea to maximize a Window as soon as it is opened using Maximize Window command. This

way you ensure that all generally visible Objects are still visible and are not hiding behind Scrollbars.

Page 25: Automation Anywhererpademo.automationanywhere.com/resources/Bot... · If automations are developed using the above principles, the result will be many smaller tasks, many being reusable

Window titles are used to identify specific Windows – avoid situations where you may open multiple

Windows with the same name. Also, consider using variables to specify Window Title, so that you can

quickly update multiple commands by making change at one place by updating variable with new value.

Automation Friendly Input Formats

Given below are some Automation non-friendly use cases:

• Multiple windows with the same title

• Varying screen resolutions

• Different OS/IE Versions/MS Office Versions

• Multiple monitors

• Interactive flash forms

• Machine or data driven slowness/variance

• Windows without titles

o Usually these are embedded as 2nd or 3rd level sub windows, like popup windows

• Drag-and-Drop functionality

o Must use Mouse moves / clicks