Best Python code snippet using autotest_python
pipeline.py
Source:pipeline.py
1'''2Build the pipeline workflow by plumbing the stages together.3'''4from ruffus import Pipeline, suffix, formatter, add_inputs, output_from5from stages import Stages6def make_pipeline(state):7 '''Build the pipeline by constructing stages and connecting them together'''8 # Build an empty pipeline9 pipeline = Pipeline(name='fastq2bam')10 # Get a list of paths to all the FASTQ files11 input_files = state.config.get_option('files')12 # Stages are dependent on the state13 stages = Stages(state)14 # The original files15 # This is a dummy stage. It is useful because it makes a node in the16 # pipeline graph, and gives the pipeline an obvious starting point.17 pipeline.originate(18 task_func=stages.original_files,19 name='original_files',20 output=input_files)21 #22 # performs fastqc on fastq inputs23 # 24 pipeline.transform(25 task_func=stages.fastqc,26 name='fastqc',27 input=output_from('original_files'),28 filter=formatter('(?P<path>.+)/(?P<filename>.+).fastq.gz'),29 output='{path[0]}/{filename[0]}_fastqc')30 #31 # converts the fastq inputs to pre-aligned bams32 #33 pipeline.transform(34 task_func=stages.fastq2bam,35 name='fastq2bam',36 input=output_from('original_files'),37 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+)_R1.fastq.gz'),38 add_inputs=add_inputs('{path[0]}/{sample[0]}_R2.fastq.gz'),39 extras=['{sample[0]}'],40 output='{path[0]}/{sample[0]}.bam')41 #42 # validates pre-aligned bams x.bam -> x.validation43 #44 pipeline.transform(45 task_func=stages.validate_prealigned_bam,46 name='validate_prealigned_bam',47 input=output_from('fastq2bam'),48 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).bam'),49 output='{path[0]}/{sample[0]}.validation')50 # aligns pre-aligned bam x.bam -> x.mapped.bam51 pipeline.transform(52 task_func=stages.align,53 name='align',54 input=output_from('validate_prealigned_bam'),55 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).validation'),56 add_inputs=add_inputs('{path[0]}/{sample[0]}.bam'),57 output='{path[0]}/{sample[0]}.mapped.bam')58 # generates stats about an aligned bam59 pipeline.transform(60 task_func=stages.align_stats_bedtools,61 name='align_stats_bedtools',62 input=output_from('align'),63 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),64 output='{path[0]}/{sample[0]}.genomecov.stats')65 # generates stats about an aligned bam66 pipeline.transform(67 task_func=stages.align_stats_picard,68 name='align_stats_picard',69 input=output_from('align'),70 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),71 output='{path[0]}/{sample[0]}.picard.stats')72 #73 # runs the Sanger variant calling pipeline74 #75 #pipeline.transform(76 # task_func=stages.analyse_wgs,77 # name='analyse_wgs',78 # input=output_from('align'),79 # filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),80 # output='{path[0]}/{sample[0]}.wgs.1.1.2/manifest')81 # runs the components of the Sanger variant calling pipeline82 pipeline.transform(83 task_func=stages.analyse_wgs_prepare,84 name='analyse_wgs_prepare',85 input=output_from('align'),86 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),87 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.prepare')88 pipeline.transform(89 task_func=stages.analyse_wgs_reference_files,90 name='analyse_wgs_reference_files',91 input=output_from('align'),92 add_inputs=add_inputs(output_from('analyse_wgs_prepare')),93 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),94 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.reference_files')95 pipeline.transform(96 task_func=stages.analyse_wgs_init,97 name='analyse_wgs_init',98 input=output_from('align'),99 add_inputs=add_inputs(output_from('analyse_wgs_reference_files')),100 filter=formatter('(?P<path>.*)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),101 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.init')102 # block 1103 pipeline.transform(104 task_func=stages.analyse_wgs_verify_WT,105 name='analyse_wgs_verify_WT',106 input=output_from('align'),107 add_inputs=add_inputs(output_from('analyse_wgs_init')),108 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),109 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.verify_WT')110 pipeline.transform(111 task_func=stages.analyse_wgs_geno,112 name='analyse_wgs_geno',113 input=output_from('align'),114 add_inputs=add_inputs(output_from('analyse_wgs_init')),115 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),116 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.geno')117 #pipeline.transform(118 # task_func=stages.analyse_wgs_cgpPindel_input,119 # name='analyse_wgs_cgpPindel_input',120 # input=output_from('align'),121 # add_inputs=add_inputs(output_from('analyse_wgs_init')),122 # filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),123 # output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.cgpPindel_input')124 pipeline.transform(125 task_func=stages.analyse_wgs_alleleCount,126 name='analyse_wgs_alleleCount',127 input=output_from('align'),128 add_inputs=add_inputs(output_from('analyse_wgs_init')),129 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),130 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.alleleCount')131 # block 2132 pipeline.transform(133 task_func=stages.analyse_wgs_cgpPindel,134 name='analyse_wgs_cgpPindel',135 input=output_from('align'),136 add_inputs=add_inputs(output_from('analyse_wgs_init')),137 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),138 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.cgpPindel')139 pipeline.transform(140 task_func=stages.analyse_wgs_BRASS_input,141 name='analyse_wgs_BRASS_input',142 input=output_from('align'),143 add_inputs=add_inputs(output_from('analyse_wgs_init')),144 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),145 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.BRASS_input')146 pipeline.transform(147 task_func=stages.analyse_wgs_BRASS_cover,148 name='analyse_wgs_BRASS_cover',149 input=output_from('align'),150 add_inputs=add_inputs(output_from('analyse_wgs_init')),151 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),152 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.BRASS_cover')153 pipeline.transform(154 task_func=stages.analyse_wgs_CaVEMan_split,155 name='analyse_wgs_CaVEMan_split',156 input=output_from('align'),157 add_inputs=add_inputs(output_from('analyse_wgs_init')),158 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),159 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.CaVEMan_split')160 # block 2.5161 pipeline.transform(162 task_func=stages.analyse_wgs_ascat,163 name='analyse_wgs_ascat',164 input=output_from('align'),165 add_inputs=add_inputs(output_from('analyse_wgs_CaVEMan_split')),166 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),167 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.ascat')168 # after block 2169 pipeline.transform(170 task_func=stages.analyse_wgs_ascat_prep,171 name='analyse_wgs_ascat_prep',172 input=output_from('align'),173 add_inputs=add_inputs(output_from('analyse_wgs_ascat')),174 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),175 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.ascat_prep')176 pipeline.transform(177 task_func=stages.analyse_wgs_pindel_prep,178 name='analyse_wgs_pindel_prep',179 input=output_from('align'),180 add_inputs=add_inputs(output_from('analyse_wgs_cgpPindel')),181 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),182 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.pindel_prep')183 # parallel block 3184 pipeline.transform(185 task_func=stages.analyse_wgs_verify_MT,186 name='analyse_wgs_verify_MT',187 input=output_from('align'), 188 add_inputs=add_inputs(output_from('analyse_wgs_verify_WT'), output_from('analyse_wgs_prepare'), output_from('analyse_wgs_ascat')),189 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),190 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.verify_MT')191 pipeline.transform(192 task_func=stages.analyse_wgs_CaVEMan,193 name='analyse_wgs_CaVEMan',194 input=output_from('align'), 195 add_inputs=add_inputs(output_from('analyse_wgs_CaVEMan_split'), output_from('analyse_wgs_ascat_prep'), output_from('analyse_wgs_cgpPindel')),196 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),197 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.CaVEMan')198 pipeline.transform(199 task_func=stages.analyse_wgs_BRASS,200 name='analyse_wgs_BRASS',201 input=output_from('align'), 202 add_inputs=add_inputs(output_from('analyse_wgs_BRASS_cover'), output_from('analyse_wgs_BRASS_input'), output_from('analyse_wgs_prepare')),203 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),204 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.BRASS')205 pipeline.transform(206 task_func=stages.analyse_wgs_cgpPindel_annot,207 name='analyse_wgs_cgpPindel_annot',208 input=output_from('align'),209 add_inputs=add_inputs(output_from('analyse_wgs_pindel_prep')),210 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),211 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.cgpPindel_annot')212 # block 5213 pipeline.transform(214 task_func=stages.analyse_wgs_cgpFlagCaVEMan,215 name='analyse_wgs_cgpFlagCaVEMan',216 input=output_from('align'),217 add_inputs=add_inputs(output_from('analyse_wgs_CaVEMan')),218 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),219 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.cgpFlagCaVEMan')220 # pre block 6221 pipeline.transform(222 task_func=stages.analyse_wgs_CaVEMan_annot_prep,223 name='analyse_wgs_CaVEMan_annot_prep',224 input=output_from('align'),225 add_inputs=add_inputs(output_from('analyse_wgs_cgpFlagCaVEMan')),226 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),227 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.CaVEMan_annot_prep')228 # pre block 6229 pipeline.transform(230 task_func=stages.analyse_wgs_caveman_prep,231 name='analyse_wgs_caveman_prep',232 input=output_from('align'),233 add_inputs=add_inputs(output_from('analyse_wgs_CaVEMan_annot_prep')),234 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),235 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.caveman_prep')236 # block 6237 pipeline.transform(238 task_func=stages.analyse_wgs_CaVEMan_annot,239 name='analyse_wgs_CaVEMan_annot',240 input=output_from('align'),241 add_inputs=add_inputs(output_from('analyse_wgs_caveman_prep')),242 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),243 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.CaVEMan_annot')244 # done245 pipeline.transform(246 task_func=stages.analyse_wgs_finish,247 name='analyse_wgs_finish',248 input=output_from('align'), 249 add_inputs=add_inputs(output_from('analyse_wgs_CaVEMan_annot'), output_from('analyse_wgs_BRASS'), output_from('analyse_wgs_cgpPindel_annot'), output_from('analyse_wgs_alleleCount'), output_from('analyse_wgs_verify_MT'), output_from('analyse_wgs_verify_WT')),250 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),251 output='{path[0]}/{sample[0]}.wgs.1.1.2-completed.finish')252 #253 # runs the delly singularity container254 #255# pipeline.transform(256# task_func=stages.delly,257# name='delly',258# input=output_from('align'),259# filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),260# output='{path[0]}/{sample[0]}.delly.completed')261 pipeline.transform(262 task_func=stages.gridss,263 name='gridss',264 input=output_from('align'),265 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),266 output='{path[0]}/{sample[0]}.gridss.completed')267 pipeline.transform(268 task_func=stages.muse,269 name='muse',270 input=output_from('align'),271 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),272 output='{path[0]}/{sample[0]}.muse.completed')273 pipeline.transform(274 task_func=stages.mutect1,275 name='mutect1',276 input=output_from('align'),277 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),278 output='{path[0]}/{sample[0]}.mutect1.completed')279# pipeline.transform(280# task_func=stages.mutect2,281# name='mutect2',282# input=output_from('align'),283# filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),284# output='{path[0]}/{sample[0]}.mutect2.completed')285 pipeline.transform(286 task_func=stages.platypus,287 name='platypus',288 input=output_from('align'),289 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),290 output='{path[0]}/{sample[0]}.platypus.completed')291 pipeline.transform(292 task_func=stages.varscan_germline,293 name='varscan_germline',294 input=output_from('align'),295 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),296 output='{path[0]}/{sample[0]}.varscan.completed')297# pipeline.transform(298# task_func=stages.varscan_germline_indel,299# name='varscan_germline_indel',300# input=output_from('align'),301# filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),302# output='{path[0]}/{sample[0]}.varscan_indel.completed')303 pipeline.transform(304 task_func=stages.hmmcopy,305 name='hmmcopy',306 input=output_from('align'),307 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),308 output='{path[0]}/{sample[0]}.hmmcopy.completed')309 pipeline.transform(310 task_func=stages.callable_bases,311 name='callable_bases',312 input=output_from('align'),313 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),314 output='{path[0]}/{sample[0]}.callable_bases.completed')315 pipeline.transform(316 task_func=stages.somatic_sniper,317 name='somatic_sniper',318 input=output_from('align'),319 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),320 output='{path[0]}/{sample[0]}.somatic_sniper.completed')321 pipeline.transform(322 task_func=stages.contest,323 name='contest',324 input=output_from('align'),325 filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),326 output='{path[0]}/{sample[0]}.contest.completed')327# pipeline.transform(328# task_func=stages.delly2,329# name='delly2',330# input=output_from('align'),331# filter=formatter('(?P<path>.+)/(?P<sample>[a-zA-Z0-9]+).mapped.bam'),332# output='{path[0]}/{sample[0]}.delly2.completed')333 ...
test_tasks_thread.py
Source:test_tasks_thread.py
2import time3import pytest4from labthings.actions import pool, thread5def test_task_with_args():6 def task_func(arg, kwarg=False):7 pass8 task_obj = thread.ActionThread(9 "task_func", target=task_func, args=("String arg",), kwargs={"kwarg": True}10 )11 assert isinstance(task_obj, threading.Thread)12 assert task_obj._target == task_func13 assert task_obj._args == ("String arg",)14 assert task_obj._kwargs == {"kwarg": True}15def test_task_without_args():16 def task_func():17 pass18 task_obj = thread.ActionThread("task_func", target=task_func)19 assert isinstance(task_obj, threading.Thread)20 assert task_obj._target == task_func21 assert task_obj._args == ()22 assert task_obj._kwargs == {}23def test_task_properties():24 def task_func(arg, kwarg=False):25 pass26 task_obj = thread.ActionThread(27 "task_func", target=task_func, args=("String arg",), kwargs={"kwarg": True}28 )29 assert task_obj.status == task_obj._status30 assert task_obj.id == task_obj._ID31 assert task_obj.status == task_obj._status32 assert task_obj.output == task_obj._return_value33def test_task_update_progress():34 def task_func():35 pool.current_action().update_progress(100)36 return37 task_obj = thread.ActionThread("task_func", target=task_func)38 task_obj.start()39 task_obj.join()40 assert task_obj.progress == 10041def test_task_update_data():42 def task_func():43 pool.current_action().update_data({"key": "value"})44 return45 task_obj = thread.ActionThread("task_func", target=task_func)46 task_obj.start()47 task_obj.join()48 assert task_obj.data == {"key": "value"}49def test_task_start():50 def task_func():51 return "Return value"52 task_obj = thread.ActionThread("task_func", target=task_func)53 assert task_obj._status == "pending"54 assert task_obj._return_value is None55 task_obj.start()56 task_obj.join()57 assert task_obj._return_value == "Return value"58 assert task_obj._status == "completed"59def test_task_get():60 def task_func():61 time.sleep(0.1)62 return "Return value"63 task_obj = thread.ActionThread("task_func", target=task_func)64 task_obj.start()65 assert task_obj.get() == "Return value"66def test_task_get_noblock():67 def task_func():68 time.sleep(0.1)69 return "Return value"70 task_obj = thread.ActionThread("task_func", target=task_func)71 task_obj.start()72 task_obj.join()73 assert task_obj.get(block=False, timeout=0) == "Return value"74def test_task_get_noblock_timeout():75 def task_func():76 time.sleep(0.1)77 return "Return value"78 task_obj = thread.ActionThread("task_func", target=task_func)79 task_obj.start()80 with pytest.raises(TimeoutError):81 assert task_obj.get(block=False, timeout=0)82@pytest.mark.filterwarnings("ignore:Exception in thread")83def test_task_exception():84 exc_to_raise = Exception("Exception message")85 def task_func():86 raise exc_to_raise87 task_obj = thread.ActionThread("task_func", target=task_func)88 task_obj.start()89 task_obj.join()90 assert task_obj._status == "error"91 assert task_obj._return_value == str(exc_to_raise)92def test_task_stop():93 def task_func():94 while not pool.current_action().stopped:95 time.sleep(0)96 task_obj = thread.ActionThread("task_func", target=task_func)97 task_obj.start()98 task_obj.started.wait()99 assert task_obj._status == "running"100 task_obj.stop()101 task_obj.join()102 assert task_obj._status == "cancelled"103 assert task_obj._return_value is None104def test_task_stop_timeout():105 def task_func():106 while True:107 time.sleep(0)108 task_obj = thread.ActionThread("task_func", target=task_func)109 task_obj.start()110 task_obj.started.wait()111 assert task_obj._status == "running"112 task_obj.stop(timeout=0)113 task_obj.join()114 assert task_obj._status == "cancelled"115 assert task_obj._return_value is None116def test_task_terminate():117 def task_func():118 while True:119 time.sleep(0.5)120 task_obj = thread.ActionThread("task_func", target=task_func)121 task_obj.start()122 task_obj.started.wait()123 assert task_obj._status == "running"124 task_obj.terminate()125 task_obj.join()126 assert task_obj._status == "cancelled"127 assert task_obj._return_value is None128def test_task_terminate_not_running():129 def task_func():130 return131 task_obj = thread.ActionThread("task_func", target=task_func)132 task_obj.start()133 task_obj.join()134 assert task_obj.terminate() is False135def test_task_log_with_incorrect_thread():136 task_obj = thread.ActionThread(None)137 task_log_handler = thread.ThreadLogHandler(task_obj, task_obj._log)138 # Should always return False if called from outside the log handlers thread139 assert task_log_handler.thread == task_obj...
test_tasks_pool.py
Source:test_tasks_pool.py
1import threading2from labthings import actions3def test_spawn_without_context(task_pool):4 def task_func():5 pass6 task_obj = task_pool.spawn("task_func", task_func)7 assert isinstance(task_obj, threading.Thread)8def test_spawn_with_context(app_ctx, task_pool):9 def task_func():10 pass11 with app_ctx.test_request_context():12 task_obj = task_pool.spawn("task_func", task_func)13 assert isinstance(task_obj, threading.Thread)14def test_update_task_data(task_pool):15 def task_func():16 actions.update_action_data({"key": "value"})17 task_obj = task_pool.spawn("task_func", task_func)18 task_obj.join()19 assert task_obj.data == {"key": "value"}20def test_update_task_data_main_thread():21 # Should do nothing22 actions.update_action_data({"key": "value"})23def test_update_task_progress(task_pool):24 def task_func():25 actions.update_action_progress(100)26 task_obj = task_pool.spawn("task_func", task_func)27 task_obj.join()28 assert task_obj.progress == 10029def test_update_task_progress_main_thread():30 # Should do nothing31 actions.update_action_progress(100)32def test_tasks_list(task_pool):33 assert all(isinstance(task_obj, threading.Thread) for task_obj in task_pool.threads)34def test_tasks_dict(task_pool):35 assert all(36 isinstance(task_obj, threading.Thread)37 for task_obj in task_pool.to_dict().values()38 )39 assert all(k == str(t.id) for k, t in task_pool.to_dict().items())40def test_discard_id(task_pool):41 def task_func():42 pass43 task_obj = task_pool.spawn("task_func", task_func)44 assert str(task_obj.id) in task_pool.to_dict()45 task_obj.join()46 task_pool.discard_id(task_obj.id)47 assert not str(task_obj.id) in task_pool.to_dict()48def test_cleanup_task(task_pool):49 import time50 def task_func():51 pass52 # Make sure at least 1 actions is around53 task_pool.spawn("task_func", task_func)54 # Wait for all actions to finish55 task_pool.join()56 assert len(task_pool.threads) > 057 task_pool.cleanup()...
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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!