8
\$\begingroup\$

I currently work as a Junior QA tester for a small software business. Before I joined, they had no automation in place to help assist them. I then got hired and resolved this by implementing Robot Framework to their system and juggle between manual testing and creating Robot scripts to assist in regression.

Instead of manually firing off the commands to start the Robot Framework to complete the scripts I made - I decided to create a Python script to do it for me. It started of being a small little time saver. And now it has become something which combines the reports into one giant report and allows to pick and choose the tests you want to fire.

Never touching Python until recently and taking a huge interest into it - I want to make sure I am doing it right and would like any pointers from people with more experience. I have tried my best to follow the PEP8 standard and tried to comment (might be too much...) my code so that others in the office (Who have no Python experience) can understand it too.

Below is my code!

"""
File Name : RunAutomation.py
Created : 16/12/16
Edited : 06/03/17
Author : John
Version : 1.3.0
Py Ver : 2.7.11

Change Log
    1.3.0 : Implemented the ability to "Pick and choose" the Test Suites you
            want. This allows the user to run any specific tests they need to
            run and not have to restart the script every time. Original idea
            on how this was meant to work. Removed whitespace in InputtedSprint
            and InputtedBuild. If all suites is selected, it is not possible to
            run other suites also. [A] takes priority.
    1.2.8 : Added all the def for all the functions when selecting from the
            menu.
    1.2.5 : Fixed the extra '/' issue with the
            name of the combined report with the Sprint var and fixed the
            extra space being added to the list of outputs.
    1.2.0 : Added the ability to combine all xml outputs at the end of
            choosing a test suite. Combines "All" outputs within the given
            directory.
    1.1.5 : Added the ability for users to input the sprint and build number
            instead of it being hard coded.
    1.1.0 : Added a menu to allow users to pick specific test suites to run
            once all of the suites have been created.
    1.0.0 : Completed working model.
"""

import os
import sys
import time
import subprocess
import glob
from collections import Counter
from collections import OrderedDict

# Vars to define the pathway for storing the logs - Makes a path way similar
# to:          C:\AutomationLogs\EPRAIS\1.9.0\S3\1.9.0-Build9
# Reason for all being split up is due to version changes, sprints, etc...
Product = "EPRAIS/"
Version = "1.9.0/"
Sprint = "S"
Build = "1.9.0-Build"

# Default location for .Robot file finding.
os.chdir("C:/TestCases/Robot/Current/EPRAIS")

# Menu Stuffs #################################################################


def cls():  # Simple function to clear the console using the windows "cls"
    os.system("cls")

# Print header. Bar of "=" with centered text.
print "=" * 78
print "\t\t\tRobot Framework Kick-Starter!"
print "=" * 78 + "\n"

# Allows the users to define the Sprint / Build. Doesnt require me to go
# into the code and manually change it.
print "Enter the current Sprint number:"
InputtedSprint = raw_input()
InputtedSprint = InputtedSprint.rstrip()
Sprint = Sprint + str(InputtedSprint) + "/"  # Extra / needed to continue path

# Similar to above - no extra / needed due to being at the end of the pathway
print "Enter the current Build number:"
InputtedBuild = raw_input()
InputtedBuild = InputtedBuild.rstrip()
Build += str(InputtedBuild)

# Includes the Pybot outputdir command and the pathway created from the
# above vars
Output = "--outputdir C:/AutomationLogs/" + Product + Version + Sprint + Build

cls()

# Prints to the user the current log save location as a pathway
print "\n"
print "=" * 78 + "\n"
print "The Pathway for this Regression Session will be:\n"
print "C:/AutomationLogs/" + Product + Version + Sprint + Build
print "\nIf this is incorrect, please restart the script.\n"

# Basically a <hr /> tag
print "=" * 78

# Printed menu to select from
print """
+++ Select Your Test Suites +++

When selecting your Test Suites,
please input the number linked
to the Suite and then a space " "
after to link more than one Suite.

For example: 1 2 6 4 12

*Duplicates will be ignored*

[1]    LoginTests.robot
[2]    PermitTests.robot
[3]    AERTests.robot
[4]    RiskTests.robot
[5]    InvestigationTests.robot
[6]    CommunicationsTests.robot
[7]    UDFTests.robot
[8]    DocumentMapTests.robot
[9]    AORTests.robot
[10]   DashboardTests.robot
[11]   Attachments.robot
[12]   MiscTests.robot
[13]   SecurityTests.robot

[D]    SandBox.robot [Debug]
[A]    All the above suites.*

*If selected along side other suites,
the other suites will be ignored and
only [A] will be run.
"""

# Defining of menu functions ##################################################


# Prints what function was used, along with <hr /> and then calls all tests
# in the order compared to the menu above - excluding the sandbox text


def AllSuites():
    print "Running All Suites . . .\n"
    print "=" * 78 + "\n"
    LoginSuite()
    PermitSuite()
    AERSuite()
    RiskSuite()
    InvestigationSuite()
    CommunicationSuite()
    UDFSuite()
    DocumentMapSuite()
    AORSuite()
    DashBoardSuite()
    AttachmentSuite()
    MiscSuite()
    SecuritySuite()

# Prints what function was used, along with <hr /> and then calls the Pybot
# commands to run the Robot tests, and then saves the logs in the correct
# dir according to what was defined by the user input


def LoginSuite():
    print "Running Login Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Login")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxLoginTest ' + Output + ' -r '
              'FireFoxLoginReport.html -l FireFoxLoginLog.html -o '
              'FireFoxLoginOutput.xml LoginTests.robot')
    print "\n"

    os.system('pybot -N ChromeLoginTest ' + Output + ' -r '
              'ChromeLoginReport.html -l ChromeLoginLog.html -o '
              'ChromeLoginOutput.xml -v Browser:Chrome LoginTests.robot')
    print "\n"

    os.system('call pybot -N EdgeLoginTest ' + Output + ' -r '
              'EdgeLoginReport.html -l EdgeLoginLog.html -o '
              'EdgeLoginOutput.xml -v Browser:Edge LoginTests.robot')
    print "\n"

###


def PermitSuite():
    print "Running Permit Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Permit")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxPermitTest ' + Output + ' -r '
              'FireFoxPermitReport.html -l FireFoxPermitLog.html -o '
              'FireFoxPermitOutput.xml PermitTests.robot')
    print "\n"

    os.system('pybot -N ChromePermitTest ' + Output + ' -r '
              'ChromePermitReport.html -l ChromePermitLog.html -o '
              'ChromePermitOutput.xml -v Browser:Chrome PermitTests.robot')
    print "\n"

    os.system('call pybot -N EdgePermitTest ' + Output + ' -r '
              'EdgePermitReport.html -l EdgePermitLog.html -o '
              'EdgePermitOutput.xml -v Browser:Edge PermitTests.robot')
    print "\n"

###


def AERSuite():
    print "Running AER Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/AER")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxAERTest ' + Output + ' -r '
              'FireFoxAERReport.html -l FireFoxAERLog.html -o '
              'FireFoxAEROutput.xml AERTests.robot')
    print "\n"

    os.system('pybot -N ChromeAERTest ' + Output + ' -r '
              'ChromeAERReport.html -l ChromeAERLog.html -o '
              'ChromeAEROutput.xml -v Browser:Chrome AERTests.robot')
    print "\n"

    os.system('call pybot -N EdgeAERTest ' + Output + ' -r '
              'EdgeAERReport.html -l EdgeAERLog.html -o '
              'EdgeAEROutput.xml -v Browser:Edge AERTests.robot')
    print "\n"

###


def RiskSuite():
    print "Running Risk Assessment Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Risk")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxRiskTest ' + Output + ' -r '
              'FireFoxRiskReport.html -l FireFoxRiskLog.html -o '
              'FireFoxRiskOutput.xml RiskTests.robot')
    print "\n"

    os.system('pybot -N ChromeRiskTest ' + Output + ' -r '
              'ChromeRiskReport.html -l ChromeRiskLog.html -o '
              'ChromeRiskOutput.xml -v Browser:Chrome RiskTests.robot')
    print "\n"

    os.system('call pybot -N EdgeRiskTest ' + Output + ' -r '
              'EdgeRiskReport.html -l EdgeRiskLog.html -o '
              'EdgeRiskOutput.xml -v Browser:Edge RiskTests.robot')
    print "\n"

###


def InvestigationSuite():
    print "Running Investigation Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Investigation")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxInvestigationTest ' + Output + ' -r '
              'FireFoxInvestigationReport.html -l '
              'FireFoxInvestigationLog.html -o '
              'FireFoxInvestigationOutput.xml InvestigationTests.robot')
    print "\n"

    os.system('pybot -N ChromeInvestigationTest ' + Output + ' -r '
              'ChromeInvestigationReport.html -l '
              'ChromeInvestigationLog.html -o '
              'ChromeInvestigationOutput.xml -v Browser:Chrome '
              'InvestigationTests.robot')
    print "\n"

    os.system('call pybot -N EdgeInvestigationTest ' + Output + ' -r '
              'EdgeInvestigationReport.html -l EdgeInvestigationLog.html -o '
              'EdgeInvestigationOutput.xml -v Browser:Edge '
              'InvestigationTests.robot')
    print "\n"

###


def CommunicationSuite():
    print "Running Communication Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Communication")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxCommunicationTest ' + Output + ' -r '
              'FireFoxCommunicationReport.html -l '
              'FireFoxCommunicationLog.html -o '
              'FireFoxCommunicationOutput.xml CommunicationTests.robot')
    print "\n"

    os.system('pybot -N ChromeCommunicationTest ' + Output + ' -r '
              'ChromeCommunicationReport.html -l '
              'ChromeCommunicationLog.html -o ChromeCommunicationOutput.xml '
              '-v Browser:Chrome CommunicationTests.robot')
    print "\n"

    os.system('call pybot -N EdgeCommunicationTest ' + Output + ' -r '
              'EdgeCommunicationReport.html -l EdgeCommunicationLog.html -o '
              'EdgeCommunicationOutput.xml -v Browser:Edge '
              'CommunicationTests.robot')
    print "\n"

###


def UDFSuite():
    print "Running UDF Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/UDF")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxUDFTest ' + Output + ' -r '
              'FireFoxUDFReport.html -l FireFoxUDFLog.html -o '
              'FireFoxUDFOutput.xml UDFTests.robot')
    print "\n"

    os.system('pybot -N ChromeUDFTest ' + Output + ' -r '
              'ChromeUDFReport.html -l ChromeUDFLog.html -o '
              'ChromeUDFOutput.xml -v Browser:Chrome UDFTests.robot')
    print "\n"

    os.system('call pybot -N EdgeUDFTest ' + Output + ' -r '
              'EdgeUDFReport.html -l EdgeUDFLog.html -o '
              'EdgeUDFOutput.xml -v Browser:Edge UDFTests.robot')
    print "\n"

###


def DocumentMapSuite():
    print "Running Document Map Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/DocumentMap")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxDocumentMapTest ' + Output + ' -r '
              'FireFoxDocumentMapReport.html -l FireFoxDocumentMapLog.html -o '
              'FireFoxDocumentMapOutput.xml DocumentMapTests.robot')
    print "\n"

    os.system('pybot -N ChromeDocumentMapTest ' + Output + ' -r '
              'ChromeDocumentMapReport.html -l ChromeDocumentMapLog.html -o '
              'ChromeDocumentMapOutput.xml -v Browser:Chrome '
              'DocumentMapTests.robot')
    print "\n"

    os.system('call pybot -N EdgeDocumentMapTest ' + Output + ' -r '
              'EdgeDocumentMapReport.html -l EdgeDocumentMapLog.html -o '
              'EdgeDocumentMapOutput.xml -v Browser:Edge '
              'DocumentMapTests.robot')
    print "\n"

###


def AORSuite():
    print "Running AOR Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/AOR")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxAORTest ' + Output + ' -r '
              'FireFoxAORReport.html -l FireFoxAORLog.html -o '
              'FireFoxAOROutput.xml AORTests.robot')
    print "\n"

    os.system('pybot -N ChromeAORTest ' + Output + ' -r '
              'ChromeAORReport.html -l ChromeAORLog.html -o '
              'ChromeAOROutput.xml -v Browser:Chrome AORTests.robot')
    print "\n"

    os.system('call pybot -N EdgeAORTest ' + Output + ' -r '
              'EdgeAORReport.html -l EdgeAORLog.html -o '
              'EdgeAOROutput.xml -v Browser:Edge AORTests.robot')
    print "\n"

###


def DashBoardSuite():
    print "Running Dashboard Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/DashBoard")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxDashBoardTest ' + Output + ' -r '
              'FireFoxDashBoardReport.html -l FireFoxDashBoardLog.html -o '
              'FireFoxDashBoardOutput.xml DashBoardTests.robot')
    print "\n"

    os.system('pybot -N ChromeDashBoardTest ' + Output + ' -r '
              'ChromeDashBoardReport.html -l ChromeDashBoardLog.html -o '
              'ChromeDashBoardOutput.xml -v Browser:Chrome '
              'DashBoardTests.robot')
    print "\n"

    os.system('call pybot -N EdgeDashBoardTest ' + Output + ' -r '
              'EdgeDashBoardReport.html -l EdgeDashBoardLog.html -o '
              'EdgeDashBoardOutput.xml -v Browser:Edge DashBoardTests.robot')
    print "\n"

###


def AttachmentSuite():
    print "Running Attachment Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Attachment")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxAttachmentTest ' + Output + ' -r '
              'FireFoxAttachmentReport.html -l FireFoxAttachmentLog.html -o '
              'FireFoxAttachmentOutput.xml AttachmentTests.robot')
    print "\n"

    os.system('pybot -N ChromeAttachmentTest ' + Output + ' -r '
              'ChromeAttachmentReport.html -l ChromeAttachmentLog.html -o '
              'ChromeAttachmentOutput.xml -v Browser:Chrome '
              'AttachmentTests.robot')
    print "\n"

    os.system('call pybot -N EdgeAttachmentTest ' + Output + ' -r '
              'EdgeAttachmentReport.html -l EdgeAttachmentLog.html -o '
              'EdgeAttachmentOutput.xml -v Browser:Edge AttachmentTests.robot')
    print "\n"

###


def MiscSuite():
    print "Running Misc Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Misc")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxMiscTest ' + Output + ' -r '
              'FireFoxMiscReport.html -l FireFoxMiscLog.html -o '
              'FireFoxMiscOutput.xml MiscTests.robot')
    print "\n"

    os.system('pybot -N ChromeMiscTest ' + Output + ' -r '
              'ChromeMiscReport.html -l ChromeMiscLog.html -o '
              'ChromeMiscOutput.xml -v Browser:Chrome MiscTests.robot')
    print "\n"

    os.system('call pybot -N EdgeMiscTest ' + Output + ' -r '
              'EdgeMiscReport.html -l EdgeMiscLog.html -o '
              'EdgeMiscOutput.xml -v Browser:Edge MiscTests.robot')
    print "\n"

###


def SecuritySuite():
    print "Running Security Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/Security")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxSecurityTest ' + Output + ' -r '
              'FireFoxSecurityReport.html -l FireFoxSecurityLog.html -o '
              'FireFoxSecurityOutput.xml SecurityTests.robot')
    print "\n"

    os.system('pybot -N ChromeSecurityTest ' + Output + ' -r '
              'ChromeSecurityReport.html -l ChromeSecurityLog.html -o '
              'ChromeSecurityOutput.xml -v Browser:Chrome SecurityTests.robot')
    print "\n"

    os.system('call pybot -N EdgeSecurityTest ' + Output + ' -r '
              'EdgeSecurityReport.html -l EdgeSecurityLog.html -o '
              'EdgeSecurityOutput.xml -v Browser:Edge SecurityTests.robot')
    print "\n"

###


def SandBoxSuite():
    print "Running SandBox Suite . . .\n"
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/SandBox")
    print "Moving to dir: %s \n" % os.getcwd()

    os.system('pybot -N FireFoxSandBoxTest ' + Output + ' -r '
              'FireFoxSandBoxReport.html -l FireFoxSandBoxLog.html -o '
              'FireFoxSandBoxOutput.xml SandBox.robot')
    print "\n"

    os.system('pybot -N ChromeSandBoxTest ' + Output + ' -r '
              'ChromeSandBoxReport.html -l ChromeSandBoxLog.html -o '
              'ChromeSandBoxOutput.xml -v Browser:Chrome SandBox.robot')
    print "\n"

    os.system('call pybot -N EdgeSandBoxTest ' + Output + ' -r '
              'EdgeSandBoxReport.html -l EdgeSandBoxLog.html -o '
              'EdgeSandBoxOutput.xml -v Browser:Edge SandBox.robot')
    print "\n"


# Selection Stuffs ############################################################
# And Calling Functions #######################################################


# List of allowed inputs, links to the menu
Options = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
           "11", "12", "13", "D", "d"]

# Makes sure the input we give for the menu is a str
MenuInput = raw_input("Enter the tests you want to fire!\n")

# Starts the timer - close as can be as it starts after you select a suite
StartTime = time.time()

# Makes all input uppercase - catches the "D" and "d"
MenuInput = MenuInput.upper()

# Splits the list so that every space is a separator for the list elements
MenuInput = MenuInput.split()

# Removes any dupes and keeps the order the same
MenuInput = list(OrderedDict.fromkeys(MenuInput))

# If there is "A" anywhere within the list, it will perform the AllSuites()
# function
if "A" in MenuInput:
    AllSuites()
else:
    for x in MenuInput:
        # Compares the MenuInput to the Options list. If an input does not
        # match then it displays the invalid input error. otherwise it passes.
        if (x not in Options) and (y for y, z in Counter(x).items() if z > 1):
            print "'" + x + "' is an invalid input. Skipping over . . . \n"

        else:
            if x == "1":
                LoginSuite()

            elif x == "2":
                PermitSuite()

            elif x == "3":
                AERSuite()

            elif x == "4":
                RiskSuite()

            elif x == "5":
                InvestigationSuite()

            elif x == "6":
                CommunicationSuite()

            elif x == "7":
                UDFSuite()

            elif x == "8":
                DocumentMapSuite()

            elif x == "9":
                AORSuite()

            elif x == "10":
                DashBoardSuite()

            elif x == "11":
                AttachmentSuite()

            elif x == "12":
                MiscSuite()

            elif x == "13":
                SecuritySuite()

            elif x == "D":
                SandBoxSuite()


# Combination of outputs ######################################################

# stops the timer and saves it to TotalTime
# Current time minus the saved time at the start equals how long tests took
TotalTime = (time.time() - StartTime)
print (time.strftime("Total time: %H:%M:%S \n", time.gmtime(TotalTime)))

# Ask to see if they want to combine all output.xml into combined report
# with all tests
AskCombine = raw_input("Test suite completed! Do you want to combine all "
                       "outputs into one report? (Y/N)\n")

# Validation check, similar to above.
while AskCombine not in ("y", "Y", "n", "N"):
    print "Incorrect input"
    AskCombine = raw_input()

# If they want to, it'll move to defined dir which stores all of the
# reports of the completed tests. It will loop through the entire dir and
# then note what *.xml files are there and assign it to the TotalXml var
if AskCombine.lower() == "y":

    os.chdir("C:/AutomationLogs/" + Product + Version + Sprint + Build)

    global FindXml
    global TotalXml
    TotalXml = ""

    # Finds all output.xml in the working directory
    for FindXml in glob.glob("*.xml"):
        TotalXml += FindXml + " "

    # Needed to remove the extra "/" off the Sprint var. So that there isn't
    # a slash in the name of the report.
    SprintSlash = Sprint[:-1]
    TotalXml = TotalXml[:-1]  # Removes following " " at the end.

    # Prints out the list of grabbed *.xml files and then runs the rebot
    # command to combine all the reports into one large report.
    print ("\nList of Output.xml files being combined:\n" + TotalXml + "\n")
    os.system('rebot -N AllCombinedTests-' + SprintSlash + '-' + Build + ' '
              '--outputdir C:/AutomationLogs/' + Product + '/Combined/'
              + Version + Sprint + Build + " " + TotalXml)

# Quits script they don't want to combine
elif AskCombine.lower() == "n":
    quit()


else:  # Should never be seen...
    print "!!!Error within Combination!!!"

print "\nPress enter to exit . . ."
raw_input()
\$\endgroup\$
4
  • \$\begingroup\$ Since you picked Python recently, is there any reason why you choose Python 2 over Python 3? \$\endgroup\$ – 301_Moved_Permanently Mar 7 '17 at 20:07
  • \$\begingroup\$ Robot Framework works for 2.7 - So I didn't want to fiddle with different versions \$\endgroup\$ – Goralight Mar 7 '17 at 20:11
  • \$\begingroup\$ Note that the PyPI page mentions that "The core framework is implemented using Python, supports both Python 2 and Python 3, and runs also on Jython (JVM), IronPython (.NET) and PyPy." \$\endgroup\$ – 301_Moved_Permanently Mar 7 '17 at 23:02
  • \$\begingroup\$ I mean the version of Robot I am using is making use of Python 2.7. I know it supports both 2 and 3. I should have worded the first comment better, my bad \$\endgroup\$ – Goralight Mar 7 '17 at 23:31
6
\$\begingroup\$

Python has a style guide, and you have a few non-compliances:

  • Imports should be alphabetically ordered (and you could combine from collections import Counter, OrderedDict)
  • Functions and variables should be named in snake_case, not CamelCase
  • You should be consistent with ' and " for string quoting

Rather than concatenating strings with +, it's more readable and efficient to use the various string formatting options in Python, e.g. 'Hello {0}'.format('world') rather than 'Hello' + 'world'.


Your code has an awful lot of duplication. Your functions vary only in the specific names being run, the structure is the same. Therefore you could reduce this duplication by extracting the names:

def run_suite(name):
    print "Running {0} Suite . . .\n".format(name)
    print "=" * 78 + "\n"

    os.chdir("C:/TestCases/Robot/Current/EPRAIS/{0}".format(name))
    print "Moving to dir: %s \n" % os.getcwd()

    ...

You also have duplication of information in e.g. which input number relates to which test. One way to simplify might be to use OOP; make a class to abstract away the details of tests:

class TestSuite(object):

    def __init__(self, name, ...):
        self.name = name
        ... 

    def run(self):
        """Call this method to run the suite."""
        ...

    def _change_working_dir(self):
        """Private methods can hide the implementation detail."""
        os.chdir("C:/TestCases/Robot/Current/EPRAIS/{0.name}".format(self))

    ...

Then you can make a list of the numbered tests:

suites = [TestSuite('Login', ...), ...]

and build the help text from it automatically:

for index, suite in enumerate(suites, start=1):
    print '[{0}] {1.name}Tests.robot'.format(index, suite)

This allows you to check valid input test numbers with e.g. if test_index in range(1, len(suites) + 1):, and run a test as suites[test_index - 1].run(). The all ('A'/'a') option is just:

for suite in suites:
    suite.run()

Rather than have the whole system run whenever the script is executed, you should define an entry point function and place it behind a if __name__ == '__main__': guard clause; this allows you to import and test/reuse the functionality elsewhere if required.


You could introduce some more input validation, see e.g. Asking the user for input until they give a valid response for common patterns.

\$\endgroup\$
1
  • \$\begingroup\$ Many thanks for your input - I will look into fixing my code and take your points on board :) \$\endgroup\$ – Goralight Mar 7 '17 at 14:01
2
\$\begingroup\$

This docstring:

"""
File Name : RunAutomation.py
Created : 16/12/16
Edited : 06/03/17
Author : John
Version : 1.3.0
Py Ver : 2.7.11

Change Log
    1.3.0 : Implemented the ability to "Pick and choose" the Test Suites you
            want. This allows the user to run any specific tests they need to
            run and not have to restart the script every time. Original idea
            on how this was meant to work. Removed whitespace in InputtedSprint
            and InputtedBuild. If all suites is selected, it is not possible to
            run other suites also. [A] takes priority.
    1.2.8 : Added all the def for all the functions when selecting from the
            menu.
    1.2.5 : Fixed the extra '/' issue with the
            name of the combined report with the Sprint var and fixed the
            extra space being added to the list of outputs.
    1.2.0 : Added the ability to combine all xml outputs at the end of
            choosing a test suite. Combines "All" outputs within the given
            directory.
    1.1.5 : Added the ability for users to input the sprint and build number
            instead of it being hard coded.
    1.1.0 : Added a menu to allow users to pick specific test suites to run
            once all of the suites have been created.
    1.0.0 : Completed working model.
"""

Is absolutely useless. The top-level docstring should describe what the module does, not what you did to the module. Something along the lines of:

"""Run automated tests for Robot Framework.

Functions of this module allows to select which tests to enable
in the Robot Framework and to run them all at once. An interactive
menu is also provided for convenience. Blah blah blah.
"""

And that's it.

The changelog should be in the history of your Git/SVN/Hg/Bzr/Whatever instead. And for the other kind of information, Python has some special purpose variables used by the help function. Among them:

__author__ = 'John'
__version__ = '1.3.0'

are the one you need. "Created" and "Edited" should also be part of the history of the version control. The file name is already populated in __file__ by the Python interpreter (with a much better accuracy). And to define the Python version to use, it is often best to put a shebang instead:

#!/usr/bin/env python2
\$\endgroup\$
1
  • \$\begingroup\$ Thanks for clarifying the main use of the top level doc string, I never really knew what I should put in there so i basically just put everything what I could think of at the time (Dumb looking back at it) I never knew about the __author__ and __version__ so thanks for that! Didn't think about the shebang! I'll add that too. Thanks for the tips, I'll apply them :) \$\endgroup\$ – Goralight Mar 7 '17 at 23:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.