How to use test_job_dir method in autotest

Best Python code snippet using autotest_python

tests.py

Source:tests.py Github

copy

Full Screen

1# -*- coding: utf-8 -*-2from django.test import TestCase3import unittest4from django.urls import reverse5from django.conf import settings6from django.utils import timezone7import socket8import pytz9from time import sleep10from io import BytesIO11import os12import uuid13from random import randint14from mothulity import views, models, forms, utils15base_dir = os.path.abspath(os.path.dirname(__file__))16hostname_production = 'xe-mothulity-dizak'17hostname_development = 'bender'18class UtilsTests(TestCase):19 """20 Tests for uploaded files validator.21 """22 def setUp(self):23 """24 Sets up class level attributes for the tests.25 Parameters26 -------27 fastq_file: str28 Path to test fastq file.29 summ_file: str30 Path to test non-fastq file.31 sinfo_raw: str32 Path to test sinfo log file.33 long_idle_nodes: int, <61>34 Number of nodes idle in queue long.35 """36 self.test_job_id = str(uuid.uuid4())37 self.submission_data_dict = {"job_name": "test-job",38 "notify_email": "test@mail.com",39 "max_ambig": 0,40 "max_homop": 8,41 # "min_length": 100,42 # "max_length": 200,43 "min_overlap": 10,44 "screen_criteria": 95,45 "chop_length": 250,46 "precluster_diffs": 2,47 "classify_seqs_cutoff": 80,48 "amplicon_type": "16S"}49 self.j_id = models.JobID(job_id=self.test_job_id)50 self.j_id.save()51 submissiondata = models.SubmissionData(52 job_id=self.j_id,53 **self.submission_data_dict,54 )55 submissiondata.save()56 self.fastq_file = "{}/tests/Mock_S280_L001_R1_001.fastq".format(base_dir)57 self.summ_file = "{}/tests/mothur.job.trim.contigs.summary".format(base_dir)58 self.machine = "headnode"59 self.cmd = "uname"60 self.cmd_out = "Linux"61 self.sinfo_file = "{}/tests/sinfo.log".format(base_dir)62 self.squeue_file = "{}/tests/squeue.log".format(base_dir)63 self.long_idle_nodes = 6164 self.accel_idle_nodes = 1265 self.accel_alloc_nodes = 366 self.JOBID_1 = 132423367 self.JOBID_2 = 132449068 self.PARTITION_1 = "accel"69 self.NAME_1 = "bash"70 self.USER_1 = "maciek"71 self.ST_1 = "R"72 self.TIME_1 = "13-09:03:01"73 self.NODES_1 = 174 self.NODELIST_1 = "phi3"75 self.PARTITION_2 = "short"76 self.NAME_2 = "bash"77 self.USER_2 = "huncwot"78 self.ST_2 = "R"79 self.TIME_2 = "5:00:01"80 self.NODES_2 = 181 self.NODELIST_2 = "n1"82 self.ref_moth_cmd = 'mothulity tests --output-dir tests --run bash --job-name test_job'83 self.test_moth_files = 'tests'84 self.test_moth_cmd_dict = {85 'job_name': 'test job',86 'id': self.test_job_id,87 'job_id_id': self.test_job_id,88 'amplicon_type': '16S',89 }90 self.test_job_dir = '{}/tests/{}/'.format(base_dir, self.test_job_id.replace('-', '_'))91 self.test_no_job_dir = '{}/tests/{}/'.format(base_dir, str(uuid.uuid4()).replace('-', '_'))92 os.system('mkdir {}'.format(self.test_job_dir))93 os.system('mkdir {}'.format(self.test_no_job_dir))94 os.system('touch {0}1.fastq {0}2.fastq {0}mothur.job.sh {0}analysis_mothur.job.zip'.format(self.test_job_dir))95 self.ref_files_to_spare = ['analysis_mothur.job.zip']96 def tearDown(self):97 """98 Distroys tests left-overs.99 """100 os.system('rm -r {}'.format(self.test_job_dir))101 os.system('rm -r {}'.format(self.test_no_job_dir))102 def test_sniff_true(self):103 """104 Tests whether utils.sniff returns <True> on fastq file.105 """106 self.assertIs(utils.sniff_file(self.fastq_file), True)107 def test_sniff_false(self):108 """109 Tests whether utils.sniff returns <False> on fastq file.110 """111 self.assertIs(utils.sniff_file(self.summ_file), False)112 def test_count_seqs(self):113 """114 Tests whether utils.count_seqs return expected reads number.115 """116 self.assertEqual(utils.count_seqs(self.fastq_file), 4779)117 def test_parse_sinfo(self):118 """119 Tests whether sinfo log file returns expected values.120 """121 with open(self.sinfo_file) as fin:122 sinfo_str = fin.read()123 self.assertEqual(utils.parse_sinfo(sinfo_str,124 partition="long",125 state="idle"),126 self.long_idle_nodes)127 self.assertEqual(utils.parse_sinfo(sinfo_str,128 partition="accel",129 state="idle"),130 self.accel_idle_nodes)131 self.assertEqual(utils.parse_sinfo(sinfo_str,132 partition="accel",133 state="alloc"),134 self.accel_alloc_nodes)135 def test_parse_squeue(self):136 """137 Test whether squeue log file returns expected values138 """139 with open(self.squeue_file) as fin:140 squeue_str = fin.read()141 self.assertEqual(utils.parse_squeue(squeue_str,142 self.JOBID_1,143 "JOBID"),144 self.JOBID_1)145 self.assertEqual(utils.parse_squeue(squeue_str,146 self.JOBID_1,147 "PARTITION"),148 self.PARTITION_1)149 self.assertEqual(utils.parse_squeue(squeue_str,150 self.JOBID_1,151 "NAME"),152 self.NAME_1)153 self.assertEqual(utils.parse_squeue(squeue_str,154 self.JOBID_1,155 "USER"),156 self.USER_1)157 self.assertEqual(utils.parse_squeue(squeue_str,158 self.JOBID_1,159 "ST"),160 self.ST_1)161 self.assertEqual(utils.parse_squeue(squeue_str,162 self.JOBID_1,163 "TIME"),164 self.TIME_1)165 self.assertEqual(utils.parse_squeue(squeue_str,166 self.JOBID_2,167 "JOBID"),168 self.JOBID_2)169 self.assertEqual(utils.parse_squeue(squeue_str,170 self.JOBID_2,171 "PARTITION"),172 self.PARTITION_2)173 self.assertEqual(utils.parse_squeue(squeue_str,174 self.JOBID_2,175 "NAME"),176 self.NAME_2)177 self.assertEqual(utils.parse_squeue(squeue_str,178 self.JOBID_2,179 "USER"),180 self.USER_2)181 self.assertEqual(utils.parse_squeue(squeue_str,182 self.JOBID_2,183 "ST"),184 self.ST_2)185 self.assertEqual(utils.parse_squeue(squeue_str,186 self.JOBID_2,187 "TIME"),188 self.TIME_2)189 # def test_ssh_cmd(self):190 # """191 # Tests whether commands via ssh are successful.192 # """193 # self.assertEqual(utils.ssh_cmd(self.cmd,194 # self.machine),195 # self.cmd_out)196 def test_render_moth_cd(self):197 """198 Tests if the mothulity command is properly rendered.199 """200 self.assertEqual(201 sorted(self.ref_moth_cmd.split(' ')),202 sorted(utils.render_moth_cmd(203 moth_files=self.test_moth_files,204 moth_opts=self.test_moth_cmd_dict,205 shell='bash'206 ).split(' '))207 )208 def test_remove_except(self):209 """210 Tests whether only unwanted files are being removed.211 """212 utils.remove_except(self.test_job_dir, '*zip', safety=False)213 self.test_job_dir_content = os.listdir(self.test_job_dir)214 self.assertEqual(215 self.test_job_dir_content,216 self.ref_files_to_spare217 )218 def test_remove_except_no_exceptions(self):219 """220 Tests if everything is removed if there is nothing spare on purpose.221 """222 utils.remove_except(self.test_job_dir, None, safety=False)223 self.test_job_dir_content = os.listdir(self.test_job_dir)224 self.assertEqual(225 self.test_job_dir_content,226 [],227 )228 def test_remove_dir_safety_off(self):229 """230 Tests whether directory is properly removed.231 """232 os.listdir(self.test_job_dir)233 self.assertEqual(234 utils.remove_dir(self.test_job_dir, safety=False),235 []236 )237 with self.assertRaises(FileNotFoundError):238 os.listdir(self.test_job_dir)239 def test_remove_dir_safety_on(self):240 """241 Tests whether directory is properly removed.242 """243 self.assertEqual(244 utils.remove_dir(self.test_job_dir, safety=True),245 [self.test_job_dir]246 )247 def test_isdone(self):248 """249 Tests if returns proper value.250 """251 self.assertTrue(utils.isdone(self.test_job_dir))252 self.assertFalse(utils.isdone(self.test_job_dir, '*foobar'))253 def test_isstale(self):254 """255 Tests if utils.isstale return proper value.256 """257 sleep(5)258 self.assertEqual(259 utils.isstale('{}1.fastq'.format(self.test_job_dir), 3),260 True,261 )262 self.assertEqual(263 utils.isstale('{}1.fastq'.format(self.test_job_dir), 1200),264 False,265 )266 def test_get_dirs_without_entries(self):267 """268 Test if utils.get_dirs_without_entries returns proper value.269 """270 self.assertEqual(271 utils.get_dirs_without_entries('{}/tests/'.format(base_dir), job_model=models.SubmissionData),272 [self.test_no_job_dir]273 )274class ViewsResponseTests(TestCase):275 """276 Tests for the response codes.277 """278 def setUp(self):279 """280 Sets up class level attributes for the tests.281 Parameters282 -------283 urls_list: list of str284 List urls postfixes to be tested by django's test client.285 """286 self.settings_domain = [287 i for i in settings.ALLOWED_HOSTS if i != 'localhost'288 ][0]289 site = models.Site(id=randint(1, 10))290 site.domain = self.settings_domain291 site.name = 'mothulity'292 site.save()293 path_settings = models.PathSettings(294 site=site,295 upload_path='/tmp/',296 hpc_path='/tmp/',297 )298 path_settings.save()299 web_server_settings = models.WebServerSettings(300 site=site,301 files_upload_expiry_time=1200,302 )303 web_server_settings.save()304 hpc_settings = models.HPCSettings(305 site=site,306 hpc_name='headnode',307 free_Ns_minimum_number=20,308 free_PHIs_minimum_number=5,309 retry_maximum_number=1,310 scheduler_interval=300,311 )312 hpc_settings.save()313 self.test_job_id = str(uuid.uuid4())314 self.submission_data_dict = {"job_name": "test-job",315 "notify_email": "test@mail.com",316 "max_ambig": 0,317 "max_homop": 8,318 # "min_length": 100,319 # "max_length": 200,320 "min_overlap": 10,321 "screen_criteria": 95,322 "chop_length": 250,323 "precluster_diffs": 2,324 "classify_seqs_cutoff": 80,325 "amplicon_type": "16S"}326 self.test_seqs_count = 42327 self.test_job_status = "pending"328 self.test_submission_time = timezone.now()329 self.j_id = models.JobID(job_id=self.test_job_id)330 self.j_id.save()331 stats = models.SeqsStats(job_id=self.j_id,332 seqs_count=self.test_seqs_count)333 stats.save()334 status = models.JobStatus(job_id=self.j_id,335 job_status=self.test_job_status,336 submission_time=self.test_submission_time)337 status.save()338 submissiondata = models.SubmissionData(job_id=self.j_id,339 **self.submission_data_dict)340 submissiondata.save()341 self.ref_single_file_name = '{}/tests/Mock_S280_L001_R1_001.fastq'.format(base_dir)342 self.ref_paired_fastq_file_name = '{}/tests/Mock_S280_L001_R2_001.fastq'.format(base_dir)343 self.ref_not_fastq_R1_file_name = '{}/tests/not_a_fastq_file_R1.fastq'.format(base_dir)344 self.ref_not_fastq_R2_file_name = '{}/tests/not_a_fastq_file_R2.fastq'.format(base_dir)345 self.ref_index_h1 = 'run mothur with a single button!'346 self.ref_submit_no_data_h2 = 'Parameters to run mothulity'347 self.ref_submit_data_submitted_h1 = '{} has been submitted'.format(submissiondata.job_name.replace('-', '_'))348 self.ref_status_h2 = '{} is {}'.format(submissiondata.job_name, self.test_job_status)349 self.ref_status_p_pending = 'It means it is waiting for resources allocation on the computing cluster.'350 self.ref_status_p_dead = 'Sorry, your job was not finished despite being processed {} times'.format(hpc_settings.retry_maximum_number + 1)351 def test_index_response_code(self):352 """353 Tests whether response code of available urls equals <200>.354 """355 response = self.client.get(reverse("mothulity:index"))356 self.assertEqual(response.status_code, 200)357 self.assertContains(response, self.ref_index_h1)358 def test_single_file_upload(self):359 with open(self.ref_single_file_name) as fin:360 response = self.client.post(361 reverse("mothulity:index"),362 {'file_field': fin}363 )364 self.assertContains(response, views.upload_errors['uneven'])365 def test_bad_files_upload(self):366 with open(self.ref_not_fastq_R1_file_name) as fin_1:367 with open(self.ref_not_fastq_R2_file_name) as fin_2:368 response = self.client.post(369 reverse("mothulity:index"),370 {'file_field': (fin_1, fin_2)}371 )372 self.assertContains(response, views.upload_errors['format'])373 def test_good_files_upload_no_remote_dir_mounted(self):374 with open(self.ref_single_file_name) as fin_1:375 with open(self.ref_paired_fastq_file_name) as fin_2:376 response = self.client.post(377 reverse("mothulity:index"),378 {'file_field': (fin_1, fin_2)},379 follow=True,380 )381 self.assertEqual(response.status_code, 200)382 self.assertContains(response, views.upload_errors['mothulity_fc'])383 @unittest.skipUnless(socket.gethostname() == hostname_production, 'Paths supposed to work on the production machine.')384 def test_good_files_upload_remote_dir_mounted(self):385 site = models.Site.objects.get(domain=self.settings_domain)386 path_settings = site.pathsettings387 path_settings.upload_path='/mnt/mothulity_HPC/jobs/'388 path_settings.hpc_path='/home/mothulity/jobs/'389 path_settings.save()390 with open(self.ref_single_file_name) as fin_1:391 with open(self.ref_paired_fastq_file_name) as fin_2:392 response = self.client.post(393 reverse("mothulity:index"),394 {'file_field': (fin_1, fin_2)},395 follow=True,396 )397 self.assertEqual(response.status_code, 200)398 self.assertContains(response, self.ref_submit_no_data_h2)399 @unittest.skipUnless(socket.gethostname() == hostname_development, 'Paths supposed to work on the development machine.')400 def test_good_files_upload_remote_dir_mounted(self):401 site = models.Site.objects.get(domain=self.settings_domain)402 path_settings = site.pathsettings403 path_settings.upload_path='/mnt/headnode/data/django/'404 path_settings.hpc_path='/home/dizak/data/django/'405 path_settings.save()406 with open(self.ref_single_file_name) as fin_1:407 with open(self.ref_paired_fastq_file_name) as fin_2:408 response = self.client.post(409 reverse("mothulity:index"),410 {'file_field': (fin_1, fin_2)},411 follow=True,412 )413 self.assertEqual(response.status_code, 200)414 self.assertContains(response, self.ref_submit_no_data_h2)415 def test_submit_no_data(self):416 response = self.client.post(417 reverse('mothulity:submit', args=(self.test_job_id,)),418 )419 self.assertEqual(response.status_code, 200)420 self.assertContains(response, self.ref_submit_no_data_h2)421 def test_submit_data_submitted(self):422 response = self.client.post(423 reverse('mothulity:submit', args=(self.test_job_id,)),424 data=self.submission_data_dict,425 )426 self.assertEqual(response.status_code, 200)427 self.assertContains(response, self.ref_submit_data_submitted_h1)428 def test_status_pending(self):429 response = self.client.get(430 reverse('mothulity:status', args=(self.test_job_id,))431 )432 self.assertEqual(response.status_code, 200)433 self.assertContains(response, self.ref_status_h2)434 self.assertContains(response, self.ref_status_p_pending)435 print(response.content)436 def test_status_dead(self):437 self.test_job = models.JobID.objects.get(job_id=self.test_job_id)438 self.test_status = models.JobStatus.objects.get(job_id=self.test_job)439 self.test_status.job_status = 'dead'440 self.test_status.save()441 self.site = site = models.Site.objects.get(442 domain=[i for i in settings.ALLOWED_HOSTS if i != 'localhost'][0]443 )444 self.hpc_settings = self.site.hpcsettings445 self.response = self.client.get(446 reverse('mothulity:status', args=(self.test_job_id,))447 )448 self.assertEqual(self.response.status_code, 200)449 self.assertContains(self.response, self.ref_status_p_dead)450class ModelsTest(TestCase):451 """452 Tests for the models database API.453 """454 def setUp(self):455 """456 Sets up class level attrubutes for the tests.457 Parameters458 -------459 test_job_id: str460 UUID created ad hoc and converted into str.461 """462 self.test_job_id = str(uuid.uuid4())463 self.submission_data_dict = {"job_name": "test-job",464 "notify_email": "test@mail.com",465 "max_ambig": 0,466 "max_homop": 8,467 # "min_length": 100,468 # "max_length": 200,469 "min_overlap": 10,470 "screen_criteria": 95,471 "chop_length": 250,472 "precluster_diffs": 2,473 "classify_seqs_cutoff": 80,474 "amplicon_type": "16S"}475 self.test_seqs_count = 42476 self.test_job_status = "pending"477 self.test_submission_time = timezone.now()478 self.j_id = models.JobID(job_id=self.test_job_id)479 self.j_id.save()480 def test_job_id(self):481 """482 Tests whether job_id is properly saved and retrieved into and from the483 model.484 """485 self.assertIs(self.j_id.job_id, self.test_job_id)486 def test_seqsstats(self):487 """488 Tests whether job_id is properly saved and retrieved into and from the489 model as well as creation of seqsstats_set connected with the job_id.490 """491 stats = models.SeqsStats(job_id=self.j_id,492 seqs_count=self.test_seqs_count)493 stats.save()494 self.assertEqual(stats.seqs_count, self.test_seqs_count)495 def test_jobstatus(self):496 """497 Tests whether job_status and submission_time are properly saved and498 retrieved.499 """500 status = models.JobStatus(job_id=self.j_id,501 job_status=self.test_job_status,502 submission_time=self.test_submission_time)503 status.save()504 self.assertIs(status.job_status, self.test_job_status)505 self.assertIs(status.submission_time, self.test_submission_time)506 def test_submissiondata(self):507 """508 Tests whether job_name is properly sanitized - dashed replaced with509 underscores510 """511 submissiondata = models.SubmissionData(job_id=self.j_id,512 **self.submission_data_dict)513 submissiondata.save()514 self.assertIs(submissiondata.job_name, self.submission_data_dict["job_name"])515class FormsTest(TestCase):516 """517 Tests for the forms.518 """519 def setUp(self):520 """521 Sets up class level attrubutes for the tests.522 """523 self.form_data = {"job_name": "test-job",524 "notify_email": "test@mail.com",525 "max_ambig": 0,526 "max_homop": 8,527 # "min_length": 100,528 # "max_length": 200,529 "min_overlap": 10,530 "screen_criteria": 95,531 "chop_length": 250,532 "precluster_diffs": 2,533 "classify_seqs_cutoff": 80,534 "amplicon_type": "16S"}535 self.clean_job_name = self.form_data["job_name"].replace("-", "_")536 def test_form_validity(self):537 form = forms.OptionsForm(self.form_data)538 self.assertTrue(form.is_valid())539 def test_form_sanitize(self):540 form = forms.OptionsForm(self.form_data)541 if form.is_valid():...

Full Screen

Full Screen

test_utils_unit.py

Source:test_utils_unit.py Github

copy

Full Screen

...19def fill_in(dir):20 open(f"{dir}/simple.sh", "w").close()21 open(f"{dir}/simple.cmd", "w").close()22@pytest.fixture23def test_job_dir():24 d = tempfile.mkdtemp()25 d = f"{d}/js_testdir"26 os.mkdir(d)27 fill_in(d)28 return d29@pytest.fixture30def test_old_dir(test_job_dir):31 d = f"{test_job_dir}/../js_newstuff"32 os.mkdir(d)33 fill_in(d)34 d = f"{test_job_dir}/../js_oldstuff"35 os.mkdir(d)36 fill_in(d)37 eightdaysago = time.time() - 691200...

Full Screen

Full Screen

train_test.py

Source:train_test.py Github

copy

Full Screen

1# Copyright 2017 Google Inc. All Rights Reserved.2#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.14import glob15import json16import os17import random18import tempfile19import unittest20from . import train21class TrainTest(unittest.TestCase):22 def setUp(self):23 self.job_dir = tempfile.mkdtemp()24 self.num_checkpoints = 1025 self.checkpoint_files = []26 self.checkpoint_steps = 10027 self.test_job_dir = tempfile.mkdtemp()28 self.test_job_file_glob = os.path.join(self.test_job_dir, "*")29 # Note that hyperparameters are intended to be constant across checkpoints30 self.hyperparameter_1 = 1731 self.hyperparameter_2 = 3.1415932 for i in range(self.num_checkpoints):33 path = os.path.join(34 self.job_dir,35 "dummy-checkpoint-{}.json".format(i)36 )37 checkpoint_data = {38 "steps": i*self.checkpoint_steps,39 "hyperparameters": {40 "hyperparameter_1": self.hyperparameter_1,41 "hyperparameter_2": self.hyperparameter_242 },43 "model": random.random()44 }45 with open(path, "w") as fp:46 json.dump(checkpoint_data, fp)47 self.checkpoint_files.append(path)48 self.garbage_file = os.path.join(self.job_dir, "garbage")49 with open(self.garbage_file, "w") as gf:50 gf.write("garbage")51 def tearDown(self):52 os.remove(self.garbage_file)53 for path in self.checkpoint_files:54 os.remove(path)55 os.rmdir(self.job_dir)56 test_job_files = glob.glob(self.test_job_file_glob)57 for path in test_job_files:58 os.remove(path)59 os.rmdir(self.test_job_dir)60 def test_get_checkpoints(self):61 checkpoints = train.get_checkpoints(self.job_dir)62 self.assertSetEqual(set(checkpoints), set(self.checkpoint_files))63 def test_checkpoint_index(self):64 indices = map(train.checkpoint_index, self.checkpoint_files)65 self.assertListEqual(indices, range(self.num_checkpoints))66 def test_latest_checkpoint_1(self):67 latest_checkpoint = train.latest_checkpoint(68 random.sample(self.checkpoint_files, self.num_checkpoints)69 )70 self.assertEqual(71 latest_checkpoint,72 (self.checkpoint_files[-1], self.num_checkpoints-1)73 )74 def test_latest_checkpoint_2(self):75 latest_checkpoint = train.latest_checkpoint([])76 self.assertEqual(latest_checkpoint, (None, None))77 def test_save_checkpoint(self):78 self.assertEqual(len(glob.glob(self.test_job_file_glob)), 0)79 checkpoint_data = {80 "test_key": "test_value"81 }82 checkpoint_file = train.save_checkpoint(83 self.test_job_dir,84 1,85 checkpoint_data86 )87 self.assertEqual(len(glob.glob(self.test_job_file_glob)), 1)88 with open(checkpoint_file) as fp:89 saved_object = json.load(fp)90 self.assertDictEqual(saved_object, checkpoint_data)91 def test_runner(self):92 self.assertEqual(len(glob.glob(self.test_job_file_glob)), 0)93 hyperparameters = {94 "hyperparameter_1": self.hyperparameter_1,95 "hyperparameter_2": self.hyperparameter_296 }97 train_steps = 10098 checkpoint_steps = 1099 train.runner(100 train.generate_trainer,101 self.test_job_dir,102 train_steps,103 checkpoint_steps,104 hyperparameters105 )106 self.assertEqual(107 len(glob.glob(self.test_job_file_glob)),108 int(train_steps/checkpoint_steps) + 1109 )110if __name__ == "__main__":...

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 autotest 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