How to use result_stats method in avocado

Best Python code snippet using avocado_python

annotations_test.py

Source:annotations_test.py Github

copy

Full Screen

1#!/usr/bin/env python2from anti_instagram import logger, wrap_test_main3from anti_instagram.AntiInstagram import ScaleAndShift, calculate_transform4from duckietown_utils.expand_variables import expand_environment5from duckietown_utils.jpg import (image_clip_255, image_cv_from_jpg_fn,6 make_images_grid)7from duckietown_utils.locate_files_impl import locate_files8from line_detector.line_detector_plot import drawLines9import cv210import numpy as np11import os12import scipy.io13import yaml14import shelve15import operator16import copy17from duckietown_utils.ipython_utils import ipython_if_guy18 19 20def merge_comparison_results(comparison_results,overall_results):21 if (comparison_results):22 if (not overall_results):23 r_vals={};24 # ipython_if_guy()25 for t in comparison_results['r_vals'].keys():26 r_vals[t]=np.array([],'float32')27 g_vals=copy.deepcopy(r_vals);28 b_vals=copy.deepcopy(r_vals);29 h_vals=copy.deepcopy(r_vals);30 s_vals=copy.deepcopy(r_vals);31 v_vals=copy.deepcopy(r_vals);32 overall_results={'average_abs_err':[],'total_pixels':0,'total_error':0,'total_regions':0,'r_vals':r_vals,'g_vals':g_vals,'b_vals':b_vals,'h_vals':h_vals,'s_vals':s_vals,'v_vals':v_vals}33 34 # ipython_if_guy()35 # max_idx,max_type=max(enumerate(comparison_results['r_vals'].keys()), key=operator.itemgetter(1))36 for t in comparison_results['r_vals'].keys():37 overall_results['r_vals'][t]=np.concatenate((overall_results['r_vals'][t],comparison_results['r_vals'][t]),0)38 overall_results['g_vals'][t]=np.concatenate((overall_results['g_vals'][t],comparison_results['g_vals'][t]),0)39 overall_results['b_vals'][t]=np.concatenate((overall_results['b_vals'][t],comparison_results['b_vals'][t]),0)40 overall_results['h_vals'][t]=np.concatenate((overall_results['h_vals'][t],comparison_results['h_vals'][t]),0)41 overall_results['s_vals'][t]=np.concatenate((overall_results['s_vals'][t],comparison_results['s_vals'][t]),0)42 overall_results['v_vals'][t]=np.concatenate((overall_results['v_vals'][t],comparison_results['v_vals'][t]),0)43 44 overall_results['total_error']=overall_results['total_error']+comparison_results['total_error']45 overall_results['total_pixels']=overall_results['total_pixels']+comparison_results['total_pixels']46 overall_results['total_regions']=overall_results['total_regions']+comparison_results['total_regions']47 48 return overall_results49def examine_dataset(dirname, out):50 logger.info(dirname)51 dirname = expand_environment(dirname)52 jpgs = locate_files(dirname, '*.jpg')53 mats = locate_files(dirname, '*.mat')54 logger.debug('I found %d jpgs and %d mats' % (len(jpgs), len(mats)))55 if len(jpgs) == 0:56 msg = 'Not enough jpgs.'57 raise ValueError(msg)58# if len(mats) == 0:59# msg = 'Not enough mats.'60# raise ValueError(msg)61 first_jpg = sorted(jpgs)[0]62 logger.debug('Using jpg %r to learn transformation.' % first_jpg)63 first_jpg_image = image_cv_from_jpg_fn(first_jpg)64 success, health, parameters = calculate_transform(first_jpg_image)65 s = ""66 s += 'success: %s\n' % str(success)67 s += 'health: %s\n' % str(health)68 s += 'parameters: %s\n' % str(parameters)69 w = os.path.join(out, 'learned_transform.txt')70 with open(w, 'w') as f:71 f.write(s)72 logger.info(s)73 74 transform = ScaleAndShift(**parameters)75 76 config_dir = '${DUCKIETOWN_ROOT}/catkin_ws/src/duckietown/config/baseline/line_detector/line_detector_node/'77 config_dir = expand_environment(config_dir)78 configurations = locate_files(config_dir, '*.yaml')79 #logger.info('configurations: %r' % configurations)80 for j in jpgs:81 summaries =[]82 83 shape = (200, 160)84 interpolation = cv2.INTER_NEAREST85 86 87 bn = os.path.splitext(os.path.basename(j))[0]88 fn = os.path.join(out, '%s.all.png' % (bn))89 90 if os.path.exists(fn):91 logger.debug('Skipping because file exists: %r' % fn)92 else:93 for c in configurations:94 logger.info('Trying %r' % c)95 name = os.path.splitext(os.path.basename(c))[0]96 if name in ['oreo', 'myrtle', 'bad_lighting', '226-night']:97 continue98 with open(c) as f:99 stuff = yaml.load(f)100 101 if not 'detector' in stuff:102 msg = 'Cannot find "detector" section in %r' % c103 raise ValueError(msg)104 105 detector = stuff['detector']106 logger.info(detector)107 if not isinstance(detector, list) and len(detector) == 2:108 raise ValueError(detector)109 110 from duckietown_utils.instantiate_utils import instantiate111 112 def LineDetectorClass():113 return instantiate(detector[0], detector[1])114 115 s = run_detection(transform, j, out, shape=shape,116 interpolation=interpolation, name=name,117 LineDetectorClass=LineDetectorClass)118 summaries.append(s)119 120 together = make_images_grid(summaries, cols=1, pad=10, bgcolor=[.5, .5, .5])121 cv2.imwrite(fn, zoom_image(together, 4))122 # ipython_if_guy()123 overall_results=[]124 comparison_results={}125 for m in mats:126 logger.debug(m)127 jpg = os.path.splitext(m)[0] + '.jpg'128 if not os.path.exists(jpg):129 msg = 'JPG %r for mat %r does not exist' % (jpg, m)130 logger.error(msg)131 else:132 frame_results=test_pair(transform, jpg, m, out)133 comparison_results[m]=frame_results134 overall_results=merge_comparison_results(comparison_results[m],overall_results)135 print "comparison_results[m]=frame_results"136 # ipython_if_guy()137 print "finished mats: "+dirname138 return overall_results139 140def zoom_image(im, zoom):141 zoom = 4142 s = (im.shape[1] * zoom, im.shape[0] * zoom)143 imz = cv2.resize(im, s, interpolation=cv2.INTER_NEAREST)144 return imz145def run_detection(transform, jpg, out, shape, interpolation,146 name, LineDetectorClass):147 image = image_cv_from_jpg_fn(jpg)148 image = cv2.resize(image, shape, interpolation=interpolation)149 150 151# bgr = bgr[bgr.shape[0] / 2:, :, :]152 image_detections = line_detection(LineDetectorClass, image)153 transformed = transform(image)154 transformed_clipped = image_clip_255(transformed)155 transformed_detections = line_detection(LineDetectorClass, transformed_clipped)156 if not os.path.exists(out):157 os.makedirs(out)158 bn = os.path.splitext(os.path.basename(jpg))[0]159 def write(postfix, im):160 fn = os.path.join(out, '%s.%s.%s.png' % (bn, name, postfix))161 cv2.imwrite(fn, zoom_image(im, 4))162 together = make_images_grid([image, # transformed,163 merge_masks_res(image_detections),164 gray2rgb(image_detections['edges']),165 image_detections['annotated'],166 167 transformed_clipped,168 merge_masks_res(transformed_detections),169 gray2rgb(transformed_detections['edges']),170 transformed_detections['annotated'],171 ], 172 173 cols=4, pad=35, bgcolor=[1, 1, 1])174 175 # write the string "name" in the upper left of image together176 cv2.putText(together, name, (0, 20), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)177 return together178def merge_masks_res(res):179 return merge_masks(res['area_white'], res['area_red'], res['area_yellow'])180def merge_masks(area_white, area_red, area_yellow):181 B, G, R = 0, 1, 2182 def white(x):183 x = gray2rgb(x)184 return x185 def red(x):186 x = gray2rgb(x)187 x[:,:,R] *= 1188 x[:,:,G] *= 0189 x[:,:,B] *= 0190 return x191 def yellow(x):192 x = gray2rgb(x)193 x[:,:,R] *= 1194 x[:,:,G] *= 1195 x[:,:,B] *= 0196 return x197 h, w = area_white.shape198 orig = [area_white, area_red, area_yellow]199 masks = [white(area_white), red(area_red), yellow(area_yellow)]200 201 res = np.zeros(shape=masks[0].shape, dtype=np.uint8)202 203 for i, m in enumerate(masks):204 nz = (orig[i] > 0) * 1.0205 assert nz.shape == (h, w), nz.shape206 207 for j in [0, 1, 2]:208 res[:,:,j] = (1-nz) * res[:,:,j].copy() + (nz) * m[:,:,j]209 210 return res211 212def test_pair(transform, jpg, mat, out):213 """ 214 jpg = filename215 mat = filename216 """217 data = scipy.io.loadmat(mat)218 regions = data['regions'].flatten()219 max_type=0;220 for r in regions:221 max_type=max(max_type,r['type'][0][0][0][0])222 r_vals={};223 for t in np.arange(max_type):224 r_vals[t+1]=np.array([],'float32')225 g_vals=copy.deepcopy(r_vals);226 b_vals=copy.deepcopy(r_vals);227 h_vals=copy.deepcopy(r_vals);228 s_vals=copy.deepcopy(r_vals);229 v_vals=copy.deepcopy(r_vals);230 result_stats={'average_abs_err':[],'total_pixels':0,'total_error':0,'total_regions':0,'r_vals':r_vals,'g_vals':g_vals,'b_vals':b_vals,'h_vals':h_vals,'s_vals':s_vals,'v_vals':v_vals}231 for r in regions:232 logger.info('region')233 x = r['x'][0][0].flatten()234 y = r['y'][0][0].flatten()235 mask = r['mask'][0][0]236 mask3=cv2.merge([mask,mask,mask])237 print 'x', x238 print 'y', y239 print 'mask shape', mask.shape240 print 'type', r['type'][0][0][0][0] # type in 1- based / matlab-based indices from the list of region types (i.e road, white, yellow, red, or what ever types were annotated) 241 print 'color', r['color'][0] # color in [r,g,b] where [r,g,b]are between 0 and 1242 t=r['type'][0][0][0][0];243 # print 'guy look here'244 region_color=r['color'][0];region_color=region_color[0][0]245 rval=region_color[0]*255.;246 gval=region_color[1]*255.;247 bval=region_color[2]*255.;248 image = image_cv_from_jpg_fn(jpg)249 transformed = transform(image)250 [b2,g2,r2]=cv2.split(transformed)251 thsv=cv2.cvtColor(transformed,cv2.cv.CV_BGR2HSV)252 [h2,s2,v2]=cv2.split(thsv)253 r2_=r2[mask.nonzero()];g2_=g2[mask.nonzero()];b2_=b2[mask.nonzero()]254 h2_=h2[mask.nonzero()];s2_=s2[mask.nonzero()];v2_=v2[mask.nonzero()]255 # ipython_if_guy()256 result_stats['r_vals'][t]=np.concatenate((result_stats['r_vals'][t],r2_),0)257 result_stats['g_vals'][t]=np.concatenate((result_stats['g_vals'][t],g2_),0)258 result_stats['b_vals'][t]=np.concatenate((result_stats['b_vals'][t],b2_),0)259 result_stats['h_vals'][t]=np.concatenate((result_stats['h_vals'][t],h2_),0)260 result_stats['s_vals'][t]=np.concatenate((result_stats['s_vals'][t],s2_),0)261 result_stats['v_vals'][t]=np.concatenate((result_stats['v_vals'][t],v2_),0)262 absdiff_img=cv2.absdiff(transformed,np.array([bval,gval,rval,0.]))263 masked_diff=cv2.multiply(np.array(absdiff_img,'float32'),np.array(mask3,'float32'))264 num_pixels=cv2.sumElems(mask)[0];265 region_error=cv2.sumElems(cv2.sumElems(masked_diff))[0];266 avg_abs_err=region_error/(num_pixels+1.);267 print 'Average abs. error', avg_abs_err268 result_stats['average_abs_err'].append(avg_abs_err)269 result_stats['total_pixels']=result_stats['total_pixels']+num_pixels270 result_stats['total_error']=result_stats['total_error']+region_error271 result_stats['total_regions']=result_stats['total_regions']+1272 # XXX: to finish273 return result_stats274def line_detection(LineDetectorClass, bgr):275 detector = LineDetectorClass()276 detector.setImage(bgr)277 image_with_lines = bgr.copy()278 # detect lines and normals279 white = detector.detectLines('white')280 yellow = detector.detectLines('yellow')281 red = detector.detectLines('red')282 # draw lines283 drawLines(image_with_lines, white.lines, (0, 0, 0))284 drawLines(image_with_lines, yellow.lines, (255, 0, 0))285 drawLines(image_with_lines, red.lines, (0, 255, 0))286 287# elif isinstance(detector, LineDetector2):288# # detect lines and normals289# lines_white, normals_white, centers_white, area_white = detector.detectLines2('white')290# lines_yellow, normals_yellow, centers_yellow, area_yellow = detector.detectLines2('yellow')291# lines_red, normals_red, centers_red, area_red = detector.detectLines2('red')292# 293# # draw lines294# drawLines(image_with_lines, lines_white, (0, 0, 0))295# drawLines(image_with_lines, lines_yellow, (255, 0, 0))296# drawLines(image_with_lines, lines_red, (0, 255, 0))297# 298 # draw normals299 #detector.drawNormals2(centers_white, normals_white, (0, 0, 0))300 #detector.drawNormals2(centers_yellow, normals_yellow, (255, 0, 0))301 #detector.drawNormals2(centers_red, normals_red, (0, 255, 0))302 303 res = {}304 res['annotated'] = image_with_lines305 res['area_white'] = white.area306 res['area_red'] = red.area307 res['area_yellow'] = yellow.area308 res['edges'] = detector.edges309 return res310# cv2.imwrite('lines_with_normal.png', detector.getImage())311def gray2rgb(gray):312 ''' 313 Converts a H x W grayscale into a H x W x 3 RGB image 314 by replicating the gray channel over R,G,B. 315 316 :param gray: grayscale317 :type gray: array[HxW](uint8),H>0,W>0318 319 :return: A RGB image in shades of gray.320 :rtype: array[HxWx3](uint8)321 '''322# assert_gray_image(gray, 'input to gray2rgb')323 rgb = np.zeros((gray.shape[0], gray.shape[1], 3), dtype='uint8')324 for i in range(3):325 rgb[:, :, i] = gray326 return rgb327def anti_instagram_annotations_test():328 base = "${DUCKIETOWN_DATA}/phase3-misc-files/so1/"329 base = expand_environment(base)330 dirs = locate_files(base, '*.iids1', alsodirs=True)331 directory_results={}332 overall_results=[]333 if not dirs:334 raise ValueError('No IIDS1 directories')335 336 for d in dirs:337 import getpass338 uname = getpass.getuser()339 out = os.path.join(os.path.dirname(d), uname, os.path.basename(d) + '.v')340 if not os.path.exists(out):341 os.makedirs(out)342 results=examine_dataset(d, out)343 overall_results=merge_comparison_results(results,overall_results)344 directory_results[d]=results345 db=shelve.open('tests_results',flag='n')346 db['directory_results'] = directory_results347 db['overall_results'] = overall_results348 db.close()349 print("overall average error: %f"%(overall_results['total_error']/overall_results['total_pixels']))350 print("overall regions checked: %f"%(overall_results['total_regions']))351 for t in overall_results['v_vals'].keys():352 print("region %f: RGB %f,%f,%f, HSV %f,%f,%f" %(t,np.mean(overall_results['r_vals'][t]),np.mean(overall_results['g_vals'][t]),np.mean(overall_results['b_vals'][t]),np.mean(overall_results['h_vals'][t]),np.mean(overall_results['s_vals'][t]),np.mean(overall_results['v_vals'][t])))353 354 ipython_if_guy()355if __name__ == '__main__':...

Full Screen

Full Screen

tasks_host.py

Source:tasks_host.py Github

copy

Full Screen

1# Copyright 2019 Google LLC2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14"""Tasks host."""15import datetime16from google.protobuf import wrappers_pb217import grpc18import six19from clusterfuzz._internal.bot import testcase_manager20from clusterfuzz._internal.bot.tasks import corpus_pruning_task21from clusterfuzz._internal.bot.untrusted_runner import file_host22from clusterfuzz._internal.datastore import data_types23from clusterfuzz._internal.protos import untrusted_runner_pb224from clusterfuzz.fuzz import engine25from . import host26def _fuzz_target_to_proto(fuzz_target):27 """Convert fuzz_target to protobuf."""28 return untrusted_runner_pb2.FuzzTarget(29 engine=fuzz_target.engine,30 project=fuzz_target.project,31 binary=fuzz_target.binary,32 )33def do_corpus_pruning(context, last_execution_failed, revision):34 """Do corpus pruning on untrusted worker."""35 cross_pollinate_fuzzers = [36 untrusted_runner_pb2.CrossPollinateFuzzer(37 fuzz_target=_fuzz_target_to_proto(cpf.fuzz_target),38 backup_bucket_name=cpf.backup_bucket_name,39 corpus_engine_name=cpf.corpus_engine_name,40 ) for cpf in context.cross_pollinate_fuzzers41 ]42 request = untrusted_runner_pb2.PruneCorpusRequest(43 fuzz_target=_fuzz_target_to_proto(context.fuzz_target),44 cross_pollinate_fuzzers=cross_pollinate_fuzzers,45 last_execution_failed=last_execution_failed,46 revision=revision)47 response = host.stub().PruneCorpus(request)48 project_qualified_name = context.fuzz_target.project_qualified_name()49 today_date = datetime.datetime.utcnow().date()50 coverage_info = data_types.CoverageInformation(51 fuzzer=project_qualified_name, date=today_date)52 # Intentionally skip edge and function coverage values as those would come53 # from fuzzer coverage cron task (see src/go/server/cron/coverage.go).54 coverage_info.corpus_size_units = response.coverage_info.corpus_size_units55 coverage_info.corpus_size_bytes = response.coverage_info.corpus_size_bytes56 coverage_info.corpus_location = response.coverage_info.corpus_location57 coverage_info.corpus_backup_location = (58 response.coverage_info.corpus_backup_location)59 coverage_info.quarantine_size_units = (60 response.coverage_info.quarantine_size_units)61 coverage_info.quarantine_size_bytes = (62 response.coverage_info.quarantine_size_bytes)63 coverage_info.quarantine_location = response.coverage_info.quarantine_location64 crashes = [65 corpus_pruning_task.CorpusCrash(66 crash_state=crash.crash_state,67 crash_type=crash.crash_type,68 crash_address=crash.crash_address,69 crash_stacktrace=crash.crash_stacktrace,70 unit_path=crash.unit_path,71 security_flag=crash.security_flag,72 ) for crash in response.crashes73 ]74 result_stats = response.cross_pollination_stats75 pollination_stats = corpus_pruning_task.CrossPollinationStats(76 project_qualified_name=result_stats.project_qualified_name,77 method=result_stats.method,78 sources=result_stats.sources,79 tags=result_stats.tags,80 initial_corpus_size=result_stats.initial_corpus_size,81 corpus_size=result_stats.corpus_size,82 initial_edge_coverage=result_stats.initial_edge_coverage,83 edge_coverage=result_stats.edge_coverage,84 initial_feature_coverage=result_stats.initial_feature_coverage,85 feature_coverage=result_stats.feature_coverage)86 return corpus_pruning_task.CorpusPruningResult(87 coverage_info=coverage_info,88 crashes=crashes,89 fuzzer_binary_name=response.fuzzer_binary_name,90 revision=response.revision,91 cross_pollination_stats=pollination_stats)92def process_testcase(engine_name, tool_name, target_name, arguments,93 testcase_path, output_path, timeout):94 """Process testcase on untrusted worker."""95 if tool_name == 'minimize':96 operation = untrusted_runner_pb2.ProcessTestcaseRequest.MINIMIZE97 else:98 operation = untrusted_runner_pb2.ProcessTestcaseRequest.CLEANSE99 rebased_testcase_path = file_host.rebase_to_worker_root(testcase_path)100 file_host.copy_file_to_worker(testcase_path, rebased_testcase_path)101 request = untrusted_runner_pb2.ProcessTestcaseRequest(102 engine=engine_name,103 operation=operation,104 target_name=target_name,105 arguments=arguments,106 testcase_path=file_host.rebase_to_worker_root(testcase_path),107 output_path=file_host.rebase_to_worker_root(output_path),108 timeout=timeout)109 response = host.stub().ProcessTestcase(request)110 rebased_output_path = file_host.rebase_to_worker_root(output_path)111 file_host.copy_file_from_worker(rebased_output_path, output_path)112 return engine.ReproduceResult(113 list(response.command), response.return_code, response.time_executed,114 response.output)115def _unpack_values(values):116 """Unpack protobuf values."""117 unpacked = {}118 for key, packed_value in six.iteritems(values):119 if packed_value.Is(wrappers_pb2.DoubleValue.DESCRIPTOR):120 value = wrappers_pb2.DoubleValue()121 elif packed_value.Is(wrappers_pb2.Int64Value.DESCRIPTOR):122 value = wrappers_pb2.Int64Value()123 elif packed_value.Is(wrappers_pb2.StringValue.DESCRIPTOR):124 value = wrappers_pb2.StringValue()125 else:126 raise ValueError('Unknown stat type for ' + key)127 packed_value.Unpack(value)128 unpacked[key] = value.value129 return unpacked130def engine_fuzz(engine_impl, target_name, sync_corpus_directory,131 testcase_directory):132 """Run engine fuzzer on untrusted worker."""133 request = untrusted_runner_pb2.EngineFuzzRequest(134 engine=engine_impl.name,135 target_name=target_name,136 sync_corpus_directory=file_host.rebase_to_worker_root(137 sync_corpus_directory),138 testcase_directory=file_host.rebase_to_worker_root(testcase_directory))139 response = host.stub().EngineFuzz(request)140 crashes = [141 engine.Crash(142 input_path=file_host.rebase_to_host_root(crash.input_path),143 stacktrace=crash.stacktrace,144 reproduce_args=crash.reproduce_args,145 crash_time=crash.crash_time) for crash in response.crashes146 ]147 unpacked_stats = _unpack_values(response.stats)148 unpacked_strategies = _unpack_values(response.strategies)149 result = engine.FuzzResult(150 logs=response.logs,151 command=list(response.command),152 crashes=crashes,153 stats=unpacked_stats,154 time_executed=response.time_executed)155 file_host.pull_testcases_from_worker()156 return result, dict(response.fuzzer_metadata), unpacked_strategies157def engine_reproduce(engine_impl, target_name, testcase_path, arguments,158 timeout):159 """Run engine reproduce on untrusted worker."""160 rebased_testcase_path = file_host.rebase_to_worker_root(testcase_path)161 file_host.copy_file_to_worker(testcase_path, rebased_testcase_path)162 request = untrusted_runner_pb2.EngineReproduceRequest(163 engine=engine_impl.name,164 target_name=target_name,165 testcase_path=rebased_testcase_path,166 arguments=arguments,167 timeout=timeout)168 try:169 response = host.stub().EngineReproduce(request)170 except grpc.RpcError as e:171 if 'TargetNotFoundError' in repr(e):172 # Resurface the right exception.173 raise testcase_manager.TargetNotFoundError('Failed to find target ' +174 target_name)175 raise176 return engine.ReproduceResult(177 list(response.command), response.return_code, response.time_executed,...

Full Screen

Full Screen

GoogleSearchPageTest.py

Source:GoogleSearchPageTest.py Github

copy

Full Screen

...29 browser.load_page()30 browser.set_search_text(self.search_text)31 browser.click_search_button()32 # time.sleep(3)33 result = browser.get_result_stats()34 except Exception as err:35 self.write_log.error(err)36 finally:37 browser.close_page()38 return result39 def write_browser_performance_info(self, browser_name, result_stats):40 self.write_log.info(41 "Browser: {} | Searched text: \"{}\" | results_count: {} | Time (sec): {}".format(browser_name,42 self.search_text,43 result_stats.split()[44 1],45 result_stats.split()[46 3][1:]))47 def run_on_chrome(self):...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run avocado automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful