(self, dir=os.getcwd(), args=[])
Performs automation tests for the Unreal project in the specified directory
Performs automation tests for the Unreal project in the specified directory
Performs automation tests for the Unreal project in the specified directory
def automationTests(self, dir=os.getcwd(), args=[]):
		'''
		Performs automation tests for the Unreal project in the specified directory
		'''
		
		# Determine if rendering should be enabled
		enableRHI = len(Utility.findArgs(args, ['--withrhi'])) > 0
		args = Utility.stripArgs(args, ['--withrhi'])
		
		# Verify that at least one argument was supplied
		if len(args) == 0:
			raise RuntimeError('at least one test name must be specified')
		
		# Gather any additional arguments to pass directly to the Editor
		extraArgs = []
		if '--' in args:
			delimIndex = args.index('--')
			extraArgs = args[delimIndex+1:]
			args = args[:delimIndex]
		
		# Build the project if it isn't already built
		Utility.printStderr('Ensuring project is built...')
		self.buildDescriptor(dir, suppressOutput=True)
		
		# Determine which arguments we are passing to the automation test commandlet
		projectFile = self.getProjectDescriptor(dir)
		if '--list' in args:
			Utility.printStderr('Retrieving automation test list...')
			print('\n'.join(self.listAutomationTests(projectFile)))
		else:
			
			# Sanitise the user-supplied arguments to prevent command injection
			runAll = '--all' in args
			runFilter = '--filter' in args
			sanitised = [arg.replace(',', '').replace(';', '') for arg in args if arg not in ['--all', '--filter']]
			command = []
			
			# Determine if we are enqueueing a 'RunAll' command
			if runAll == True:
				command.append('RunAll')
			
			# Determine if we are enqueueing a 'RunFilter' command
			if runFilter == True and len(sanitised) > 0:
				command.append('RunFilter ' + sanitised.pop(0))
			
			# Enqueue a 'RunTests' command for any individual test names that were specified
			if len(sanitised) > 0:
				command.append('RunTests Now ' + '+'.join(sanitised))
			
			# Attempt to run the automation tests
			Utility.printStderr('Running automation tests...')
			logOutput = self.runAutomationCommands(projectFile, command, extraArgs, capture=True, enableRHI=enableRHI)
			
			# Propagate the log output
			print(logOutput.stdout)
			print(logOutput.stderr)
			
			# Detect abnormal exit conditions (those not triggered by `automation quit`)
			if 'PlatformMisc::RequestExit(' not in logOutput.stdout:
				sys.exit(1)
			
			# Since UE4 doesn't consistently produce accurate exit codes across all platforms, we need to rely on
			# text-based heuristics to detect failed automation tests or errors related to not finding any tests to run
			errorStrings = [
				'Incorrect automation command syntax!',
				'Automation Test Failed',
				'Result={Failed}',
				'Found 0 Automation Tests, based on',
				'is not a valid flag to filter on!'
			]
			for errorStr in errorStrings:
				if errorStr in logOutput.stdout:
					sys.exit(1)
			
			# If an explicit exit code was specified in the output text then identify it and propagate it
			match = re.search('TEST COMPLETE\\. EXIT CODE: ([0-9]+)', logOutput.stdout + logOutput.stderr)
			if match is not None:
				sys.exit(int(match.group(1)))
def automationTests ( self , dir = os . getcwd ( ) , args = [ ] ) : # Determine if rendering should be enabled enableRHI = len ( Utility . findArgs ( args , [ '--withrhi' ] ) ) > 0 args = Utility . stripArgs ( args , [ '--withrhi' ] ) # Verify that at least one argument was supplied if len ( args ) == 0 : raise RuntimeError ( 'at least one test name must be specified' ) # Gather any additional arguments to pass directly to the Editor extraArgs = [ ] if '--' in args : delimIndex = args . index ( '--' ) extraArgs = args [ delimIndex + 1 : ] args = args [ : delimIndex ] # Build the project if it isn't already built Utility . printStderr ( 'Ensuring project is built...' ) self . buildDescriptor ( dir , suppressOutput = True ) # Determine which arguments we are passing to the automation test commandlet projectFile = self . getProjectDescriptor ( dir ) if '--list' in args : Utility . printStderr ( 'Retrieving automation test list...' ) print ( '\n' . join ( self . listAutomationTests ( projectFile ) ) ) else : # Sanitise the user-supplied arguments to prevent command injection runAll = '--all' in args runFilter = '--filter' in args sanitised = [ arg . replace ( ',' , '' ) . replace ( ';' , '' ) for arg in args if arg not in [ '--all' , '--filter' ] ] command = [ ] # Determine if we are enqueueing a 'RunAll' command if runAll == True : command . append ( 'RunAll' ) # Determine if we are enqueueing a 'RunFilter' command if runFilter == True and len ( sanitised ) > 0 : command . append ( 'RunFilter ' + sanitised . pop ( 0 ) ) # Enqueue a 'RunTests' command for any individual test names that were specified if len ( sanitised ) > 0 : command . append ( 'RunTests Now ' + '+' . join ( sanitised ) ) # Attempt to run the automation tests Utility . printStderr ( 'Running automation tests...' ) logOutput = self . runAutomationCommands ( projectFile , command , extraArgs , capture = True , enableRHI = enableRHI ) # Propagate the log output print ( logOutput . stdout ) print ( logOutput . stderr ) # Detect abnormal exit conditions (those not triggered by `automation quit`) if 'PlatformMisc::RequestExit(' not in logOutput . stdout : sys . exit ( 1 ) # Since UE4 doesn't consistently produce accurate exit codes across all platforms, we need to rely on # text-based heuristics to detect failed automation tests or errors related to not finding any tests to run errorStrings = [ 'Incorrect automation command syntax!' , 'Automation Test Failed' , 'Result={Failed}' , 'Found 0 Automation Tests, based on' , 'is not a valid flag to filter on!' ] for errorStr in errorStrings : if errorStr in logOutput . stdout : sys . exit ( 1 ) # If an explicit exit code was specified in the output text then identify it and propagate it match = re . search ( 'TEST COMPLETE\\. EXIT CODE: ([0-9]+)' , logOutput . stdout + logOutput . stderr ) if match is not None : sys . exit ( int ( match . group ( 1 ) ) )