Best Python code snippet using sure_python
import_export_tests.py
Source:import_export_tests.py
...40 return "".join(41 random.choice(string.ascii_lowercase + string.digits)42 for _ in range(24)43 )44 def _new_dir(self):45 return os.path.join(self._tmp_dir, self._new_name())46class ImageExportCoersionTests(ImageDatasetTests):47 @drop_datasets48 def test_field_inference(self):49 sample = fo.Sample(50 filepath=self._new_image(),51 ground_truth=fo.Detections(52 detections=[53 fo.Detection(54 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],55 ),56 fo.Detection(57 label="dog", bounding_box=[0.5, 0.5, 0.4, 0.4],58 ),59 ]60 ),61 )62 dataset = fo.Dataset()63 dataset.add_sample(sample)64 #65 # A field of appropriate type is inferred66 #67 export_dir = self._new_dir()68 dataset.export(69 export_dir=export_dir, dataset_type=fo.types.COCODetectionDataset,70 )71 #72 # Multiple compatible field types exist, but the first one is still73 # chosen and used74 #75 dataset.clone_sample_field("ground_truth", "predictions")76 export_dir = self._new_dir()77 dataset.export(78 export_dir=export_dir, dataset_type=fo.types.COCODetectionDataset,79 )80 @drop_datasets81 def test_patch_exports(self):82 sample = fo.Sample(83 filepath=self._new_image(),84 ground_truth=fo.Detections(85 detections=[86 fo.Detection(87 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],88 ),89 fo.Detection(90 label="dog", bounding_box=[0.5, 0.5, 0.4, 0.4],91 ),92 ]93 ),94 )95 dataset = fo.Dataset()96 dataset.add_sample(sample)97 #98 # No label field is provided; only images are exported99 #100 export_dir = self._new_dir()101 dataset.export(102 export_dir=export_dir, dataset_type=fo.types.ImageDirectory,103 )104 #105 # A detections field is provided, so the object patches are exported as106 # a directory of images107 #108 export_dir = self._new_dir()109 dataset.export(110 export_dir=export_dir,111 dataset_type=fo.types.ImageDirectory,112 label_field="ground_truth",113 )114 dataset2 = fo.Dataset.from_dir(115 dataset_dir=export_dir, dataset_type=fo.types.ImageDirectory,116 )117 self.assertEqual(118 len(dataset2), dataset.count("ground_truth.detections")119 )120 #121 # A detections field is provided, so the object patches are exported as122 # an image classification directory tree123 #124 export_dir3 = self._new_dir()125 dataset.export(126 export_dir=export_dir3,127 dataset_type=fo.types.ImageClassificationDirectoryTree,128 label_field="ground_truth",129 )130 dataset3 = fo.Dataset.from_dir(131 dataset_dir=export_dir3,132 dataset_type=fo.types.ImageClassificationDirectoryTree,133 )134 self.assertEqual(135 len(dataset3), dataset.count("ground_truth.detections")136 )137 @drop_datasets138 def test_single_label_to_lists(self):139 sample = fo.Sample(140 filepath=self._new_image(),141 ground_truth=fo.Detection(142 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],143 ),144 )145 dataset = fo.Dataset()146 dataset.add_sample(sample)147 #148 # The `ground_truth` field has type `Detection`, but COCO format149 # expects `Detections`, so the labels are automatically coerced to150 # single-label lists151 #152 export_dir4 = self._new_dir()153 dataset.export(154 export_dir=export_dir4,155 dataset_type=fo.types.COCODetectionDataset,156 label_field="ground_truth",157 )158 @drop_datasets159 def test_classification_as_detections(self):160 sample = fo.Sample(161 filepath=self._new_image(), animal=fo.Classification(label="cat"),162 )163 dataset = fo.Dataset()164 dataset.add_sample(sample)165 #166 # The `animal` field is exported as detections that span entire images167 #168 export_dir = self._new_dir()169 dataset.export(170 export_dir=export_dir,171 dataset_type=fo.types.COCODetectionDataset,172 label_field="animal",173 )174 dataset2 = fo.Dataset.from_dir(175 dataset_dir=export_dir,176 dataset_type=fo.types.COCODetectionDataset,177 label_field="animal",178 )179 bounding_box = dataset2.first().animal.detections[0].bounding_box180 self.assertTrue(np.allclose(bounding_box, [0, 0, 1, 1]))181class UnlabeledImageDatasetTests(ImageDatasetTests):182 def _make_dataset(self):183 samples = [fo.Sample(filepath=self._new_image()) for _ in range(5)]184 dataset = fo.Dataset()185 dataset.add_samples(samples)186 return dataset187 @drop_datasets188 def test_image_directory(self):189 dataset = self._make_dataset()190 export_dir = self._new_dir()191 dataset.export(192 export_dir=export_dir, dataset_type=fo.types.ImageDirectory,193 )194 dataset2 = fo.Dataset.from_dir(195 dataset_dir=export_dir, dataset_type=fo.types.ImageDirectory,196 )197 self.assertEqual(len(dataset), len(dataset2))198class ImageClassificationDatasetTests(ImageDatasetTests):199 def _make_dataset(self):200 samples = [201 fo.Sample(202 filepath=self._new_image(),203 predictions=fo.Classification(label="cat", confidence=0.9),204 ),205 fo.Sample(206 filepath=self._new_image(),207 predictions=fo.Classification(label="dog", confidence=0.95),208 ),209 fo.Sample(filepath=self._new_image()),210 ]211 dataset = fo.Dataset()212 dataset.add_samples(samples)213 return dataset214 @drop_datasets215 def test_fiftyone_image_classification_dataset(self):216 dataset = self._make_dataset()217 # Standard format218 export_dir = self._new_dir()219 dataset.export(220 export_dir=export_dir,221 dataset_type=fo.types.FiftyOneImageClassificationDataset,222 )223 dataset2 = fo.Dataset.from_dir(224 dataset_dir=export_dir,225 dataset_type=fo.types.FiftyOneImageClassificationDataset,226 label_field="predictions",227 )228 self.assertEqual(len(dataset), len(dataset2))229 self.assertEqual(230 dataset.count("predictions"), dataset2.count("predictions")231 )232 # Include confidence233 export_dir = self._new_dir()234 dataset.export(235 export_dir=export_dir,236 dataset_type=fo.types.FiftyOneImageClassificationDataset,237 include_confidence=True,238 )239 dataset2 = fo.Dataset.from_dir(240 dataset_dir=export_dir,241 dataset_type=fo.types.FiftyOneImageClassificationDataset,242 label_field="predictions",243 )244 confs = dataset.values("predictions.confidence", missing_value=-1)245 confs2 = dataset2.values("predictions.confidence", missing_value=-1)246 self.assertEqual(len(dataset), len(dataset2))247 # sorting is necessary because sample order is arbitrary248 self.assertTrue(np.allclose(sorted(confs), sorted(confs2)))249 # Labels-only250 data_path = self.images_dir251 labels_path = os.path.join(self._new_dir(), "labels.json")252 dataset.export(253 dataset_type=fo.types.FiftyOneImageClassificationDataset,254 labels_path=labels_path,255 )256 dataset2 = fo.Dataset.from_dir(257 dataset_type=fo.types.FiftyOneImageClassificationDataset,258 data_path=data_path,259 labels_path=labels_path,260 label_field="predictions",261 )262 self.assertEqual(len(dataset), len(dataset2))263 self.assertSetEqual(264 set(dataset.values("filepath")), set(dataset2.values("filepath")),265 )266 self.assertEqual(267 dataset.count("predictions"), dataset2.count("predictions"),268 )269 @drop_datasets270 def test_image_classification_directory_tree(self):271 dataset = self._make_dataset()272 # Standard format273 export_dir = self._new_dir()274 dataset.export(275 export_dir=export_dir,276 dataset_type=fo.types.ImageClassificationDirectoryTree,277 )278 dataset2 = fo.Dataset.from_dir(279 dataset_dir=export_dir,280 dataset_type=fo.types.ImageClassificationDirectoryTree,281 label_field="predictions",282 )283 self.assertEqual(len(dataset), len(dataset2))284 self.assertEqual(285 dataset.count("predictions"), dataset2.count("predictions")286 )287 @drop_datasets288 def test_tf_image_classification_dataset(self):289 dataset = self._make_dataset()290 # Standard format291 export_dir = self._new_dir()292 images_dir = self._new_dir()293 dataset.export(294 export_dir=export_dir,295 dataset_type=fo.types.TFImageClassificationDataset,296 )297 dataset2 = fo.Dataset.from_dir(298 dataset_dir=export_dir,299 dataset_type=fo.types.TFImageClassificationDataset,300 images_dir=images_dir,301 label_field="predictions",302 )303 self.assertEqual(len(dataset), len(dataset2))304 self.assertEqual(305 dataset.count("predictions"), dataset2.count("predictions")306 )307 # Direct records path w/ sharding308 tf_records_path = os.path.join(self._new_dir(), "tf.records")309 tf_records_patt = tf_records_path + "-*-of-*"310 images_dir = self._new_dir()311 dataset.export(312 dataset_type=fo.types.TFImageClassificationDataset,313 tf_records_path=tf_records_path,314 num_shards=2,315 )316 dataset2 = fo.Dataset.from_dir(317 dataset_type=fo.types.TFImageClassificationDataset,318 tf_records_path=tf_records_patt,319 images_dir=images_dir,320 label_field="predictions",321 )322 self.assertEqual(len(dataset), len(dataset2))323 self.assertEqual(324 dataset.count("predictions"), dataset2.count("predictions")325 )326class ImageDetectionDatasetTests(ImageDatasetTests):327 def _make_dataset(self):328 samples = [329 fo.Sample(330 filepath=self._new_image(),331 predictions=fo.Detections(332 detections=[333 fo.Detection(334 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],335 ),336 fo.Detection(337 label="dog", bounding_box=[0.5, 0.5, 0.4, 0.4],338 ),339 ]340 ),341 ),342 fo.Sample(343 filepath=self._new_image(),344 predictions=fo.Detections(345 detections=[346 fo.Detection(347 label="cat",348 bounding_box=[0.1, 0.1, 0.4, 0.4],349 confidence=0.9,350 age=51,351 cute=True,352 mood="surly",353 ),354 fo.Detection(355 label="dog",356 bounding_box=[0.5, 0.5, 0.4, 0.4],357 confidence=0.95,358 age=52,359 cute=False,360 mood="derpy",361 ),362 ]363 ),364 ),365 fo.Sample(filepath=self._new_image()),366 ]367 dataset = fo.Dataset()368 dataset.add_samples(samples)369 return dataset370 @drop_datasets371 def test_fiftyone_image_detection_dataset(self):372 dataset = self._make_dataset()373 # Standard format374 export_dir = self._new_dir()375 dataset.export(376 export_dir=export_dir,377 dataset_type=fo.types.FiftyOneImageDetectionDataset,378 )379 dataset2 = fo.Dataset.from_dir(380 dataset_dir=export_dir,381 dataset_type=fo.types.FiftyOneImageDetectionDataset,382 label_field="predictions",383 )384 self.assertEqual(len(dataset), len(dataset2))385 self.assertEqual(386 dataset.count("predictions.detections"),387 dataset2.count("predictions.detections"),388 )389 self.assertEqual(390 dataset.distinct("predictions.detections.confidence"),391 dataset2.distinct("predictions.detections.confidence"),392 )393 self.assertEqual(394 dataset.distinct("predictions.detections.age"),395 dataset2.distinct("predictions.detections.age"),396 )397 self.assertEqual(398 dataset.distinct("predictions.detections.cute"),399 dataset2.distinct("predictions.detections.cute"),400 )401 self.assertEqual(402 dataset.distinct("predictions.detections.mood"),403 dataset2.distinct("predictions.detections.mood"),404 )405 # Labels-only406 data_path = self.images_dir407 labels_path = os.path.join(self._new_dir(), "labels.json")408 dataset.export(409 dataset_type=fo.types.FiftyOneImageDetectionDataset,410 labels_path=labels_path,411 )412 dataset2 = fo.Dataset.from_dir(413 dataset_type=fo.types.FiftyOneImageDetectionDataset,414 data_path=data_path,415 labels_path=labels_path,416 label_field="predictions",417 )418 self.assertEqual(len(dataset), len(dataset2))419 self.assertSetEqual(420 set(dataset.values("filepath")), set(dataset2.values("filepath")),421 )422 self.assertEqual(423 dataset.count("predictions.detections"),424 dataset2.count("predictions.detections"),425 )426 @drop_datasets427 def test_tf_object_detection_dataset(self):428 dataset = self._make_dataset()429 # Standard format430 export_dir = self._new_dir()431 images_dir = self._new_dir()432 dataset.export(433 export_dir=export_dir,434 dataset_type=fo.types.TFObjectDetectionDataset,435 )436 dataset2 = fo.Dataset.from_dir(437 dataset_dir=export_dir,438 dataset_type=fo.types.TFObjectDetectionDataset,439 images_dir=images_dir,440 label_field="predictions",441 )442 self.assertEqual(len(dataset), len(dataset2))443 self.assertEqual(444 dataset.count("predictions.detections"),445 dataset2.count("predictions.detections"),446 )447 # Direct records path w/ sharding448 tf_records_path = os.path.join(self._new_dir(), "tf.records")449 tf_records_patt = tf_records_path + "-*-of-*"450 images_dir = self._new_dir()451 dataset.export(452 dataset_type=fo.types.TFObjectDetectionDataset,453 tf_records_path=tf_records_path,454 num_shards=2,455 )456 dataset2 = fo.Dataset.from_dir(457 dataset_type=fo.types.TFObjectDetectionDataset,458 tf_records_path=tf_records_patt,459 images_dir=images_dir,460 label_field="predictions",461 )462 self.assertEqual(len(dataset), len(dataset2))463 self.assertEqual(464 dataset.count("predictions.detections"),465 dataset2.count("predictions.detections"),466 )467 @drop_datasets468 def test_coco_detection_dataset(self):469 dataset = self._make_dataset()470 # Standard format471 export_dir = self._new_dir()472 dataset.export(473 export_dir=export_dir, dataset_type=fo.types.COCODetectionDataset,474 )475 dataset2 = fo.Dataset.from_dir(476 dataset_dir=export_dir,477 dataset_type=fo.types.COCODetectionDataset,478 label_field="predictions",479 )480 self.assertEqual(len(dataset), len(dataset2))481 self.assertEqual(482 dataset.count("predictions.detections"),483 dataset2.count("predictions.detections"),484 )485 self.assertEqual(486 dataset.distinct("predictions.detections.confidence"),487 dataset2.distinct("predictions.detections.confidence"),488 )489 self.assertEqual(490 dataset.distinct("predictions.detections.age"),491 dataset2.distinct("predictions.detections.age"),492 )493 self.assertEqual(494 dataset.distinct("predictions.detections.cute"),495 dataset2.distinct("predictions.detections.cute"),496 )497 self.assertEqual(498 dataset.distinct("predictions.detections.mood"),499 dataset2.distinct("predictions.detections.mood"),500 )501 # Omit extra attributes502 export_dir = self._new_dir()503 dataset.export(504 export_dir=export_dir,505 dataset_type=fo.types.COCODetectionDataset,506 extra_attrs=False,507 )508 dataset2 = fo.Dataset.from_dir(509 dataset_dir=export_dir,510 dataset_type=fo.types.COCODetectionDataset,511 label_field="predictions",512 )513 self.assertEqual(dataset2.distinct("predictions.detections.age"), [])514 self.assertEqual(dataset2.distinct("predictions.detections.cute"), [])515 self.assertEqual(dataset2.distinct("predictions.detections.mood"), [])516 # Labels-only517 data_path = self.images_dir518 labels_path = os.path.join(self._new_dir(), "labels.json")519 dataset.export(520 dataset_type=fo.types.COCODetectionDataset,521 labels_path=labels_path,522 )523 dataset2 = fo.Dataset.from_dir(524 dataset_type=fo.types.COCODetectionDataset,525 data_path=data_path,526 labels_path=labels_path,527 label_field="predictions",528 )529 self.assertEqual(len(dataset), len(dataset2))530 self.assertSetEqual(531 set(dataset.values("filepath")), set(dataset2.values("filepath")),532 )533 self.assertEqual(534 dataset.count("predictions.detections"),535 dataset2.count("predictions.detections"),536 )537 @drop_datasets538 def test_voc_detection_dataset(self):539 dataset = self._make_dataset()540 # Standard format541 export_dir = self._new_dir()542 view = dataset.limit(2)543 view.export(544 export_dir=export_dir, dataset_type=fo.types.VOCDetectionDataset,545 )546 dataset2 = fo.Dataset.from_dir(547 dataset_dir=export_dir,548 dataset_type=fo.types.VOCDetectionDataset,549 label_field="predictions",550 )551 self.assertEqual(len(view), len(dataset2))552 self.assertEqual(553 view.count("predictions.detections"),554 dataset2.count("predictions.detections"),555 )556 self.assertEqual(557 view.distinct("predictions.detections.age"),558 dataset2.distinct("predictions.detections.age"),559 )560 self.assertEqual(561 view.distinct("predictions.detections.cute"),562 dataset2.distinct("predictions.detections.cute"),563 )564 self.assertEqual(565 view.distinct("predictions.detections.mood"),566 dataset2.distinct("predictions.detections.mood"),567 )568 # Handle unlabeled data569 export_dir = self._new_dir()570 dataset.export(571 export_dir=export_dir, dataset_type=fo.types.VOCDetectionDataset,572 )573 dataset2 = fo.Dataset.from_dir(574 dataset_dir=export_dir,575 dataset_type=fo.types.VOCDetectionDataset,576 label_field="predictions",577 include_all_data=True,578 )579 self.assertEqual(len(dataset), len(dataset2))580 # Labels-only581 data_path = self.images_dir582 labels_path = os.path.join(self._new_dir(), "labels.xml")583 dataset.export(584 dataset_type=fo.types.VOCDetectionDataset, labels_path=labels_path,585 )586 dataset2 = fo.Dataset.from_dir(587 dataset_type=fo.types.VOCDetectionDataset,588 data_path=data_path,589 labels_path=labels_path,590 label_field="predictions",591 include_all_data=True,592 )593 self.assertEqual(len(dataset), len(dataset2))594 self.assertSetEqual(595 set(dataset.values("filepath")), set(dataset2.values("filepath")),596 )597 self.assertEqual(598 dataset.count("predictions.detections"),599 dataset2.count("predictions.detections"),600 )601 @drop_datasets602 def test_kitti_detection_dataset(self):603 dataset = self._make_dataset()604 # Standard format605 export_dir = self._new_dir()606 view = dataset.limit(2)607 view.export(608 export_dir=export_dir, dataset_type=fo.types.KITTIDetectionDataset,609 )610 dataset2 = fo.Dataset.from_dir(611 dataset_dir=export_dir,612 dataset_type=fo.types.KITTIDetectionDataset,613 label_field="predictions",614 )615 self.assertEqual(len(view), len(dataset2))616 self.assertEqual(617 view.count("predictions.detections"),618 dataset2.count("predictions.detections"),619 )620 self.assertEqual(621 view.distinct("predictions.detections.confidence"),622 dataset2.distinct("predictions.detections.confidence"),623 )624 # Handle unlabeled data625 export_dir = self._new_dir()626 dataset.export(627 export_dir=export_dir, dataset_type=fo.types.KITTIDetectionDataset,628 )629 dataset2 = fo.Dataset.from_dir(630 dataset_dir=export_dir,631 dataset_type=fo.types.KITTIDetectionDataset,632 label_field="predictions",633 include_all_data=True,634 )635 self.assertEqual(len(dataset), len(dataset2))636 # Labels-only637 data_path = self.images_dir638 labels_path = os.path.join(self._new_dir(), "labels/")639 dataset.export(640 dataset_type=fo.types.KITTIDetectionDataset,641 labels_path=labels_path,642 )643 dataset2 = fo.Dataset.from_dir(644 dataset_type=fo.types.KITTIDetectionDataset,645 data_path=data_path,646 labels_path=labels_path,647 label_field="predictions",648 include_all_data=True,649 )650 self.assertEqual(len(dataset), len(dataset2))651 self.assertSetEqual(652 set(dataset.values("filepath")), set(dataset2.values("filepath")),653 )654 self.assertEqual(655 dataset.count("predictions.detections"),656 dataset2.count("predictions.detections"),657 )658 @drop_datasets659 def test_yolov4_dataset(self):660 dataset = self._make_dataset()661 # Standard format662 export_dir = self._new_dir()663 dataset.export(664 export_dir=export_dir,665 dataset_type=fo.types.YOLOv4Dataset,666 label_field="predictions",667 )668 dataset2 = fo.Dataset.from_dir(669 dataset_dir=export_dir,670 dataset_type=fo.types.YOLOv4Dataset,671 label_field="predictions",672 )673 self.assertEqual(len(dataset), len(dataset2))674 self.assertEqual(675 dataset.count("predictions.detections"),676 dataset2.count("predictions.detections"),677 )678 @drop_datasets679 def test_yolov5_dataset(self):680 dataset = self._make_dataset()681 # Standard format682 export_dir = self._new_dir()683 dataset.export(684 export_dir=export_dir, dataset_type=fo.types.YOLOv5Dataset,685 )686 dataset2 = fo.Dataset.from_dir(687 dataset_dir=export_dir,688 dataset_type=fo.types.YOLOv5Dataset,689 label_field="predictions",690 )691 self.assertEqual(len(dataset), len(dataset2))692 self.assertEqual(693 dataset.count("predictions.detections"),694 dataset2.count("predictions.detections"),695 )696class ImageSegmentationDatasetTests(ImageDatasetTests):697 def _make_dataset(self):698 mask1 = np.zeros((128, 128), dtype=np.uint8)699 mask1[32:96, 32:96] = 255700 mask2 = 255 * np.ones((128, 128), dtype=np.uint8)701 mask2[32:96, 32:96] = 0702 instance1 = np.zeros((32, 32), dtype=bool)703 instance1[8:24, 8:24] = True704 instance2 = np.ones((32, 32), dtype=bool)705 instance2[8:24, 8:24] = False706 samples = [707 fo.Sample(708 filepath=self._new_image(),709 segmentations=fo.Segmentation(mask=mask1),710 detections=fo.Detections(711 detections=[712 fo.Detection(713 label="cat",714 bounding_box=[0.1, 0.1, 0.4, 0.4],715 mask=instance1,716 ),717 fo.Detection(718 label="dog",719 bounding_box=[0.5, 0.5, 0.4, 0.4],720 mask=instance2,721 ),722 ]723 ),724 polylines=fo.Polylines(725 polylines=[726 fo.Polyline(727 label="cat",728 points=[729 [730 (0.1, 0.1),731 (0.5, 0.1),732 (0.5, 0.5),733 (0.1, 0.5),734 ]735 ],736 filled=True,737 ),738 fo.Polyline(739 label="dog",740 points=[741 [742 (0.5, 0.5),743 (0.9, 0.5),744 (0.9, 0.9),745 (0.5, 0.9),746 ]747 ],748 filled=True,749 ),750 ]751 ),752 ),753 fo.Sample(754 filepath=self._new_image(),755 segmentations=fo.Segmentation(mask=mask2),756 detections=fo.Detections(757 detections=[758 fo.Detection(759 label="cat",760 bounding_box=[0.1, 0.1, 0.4, 0.4],761 mask=instance2,762 ),763 fo.Detection(764 label="dog",765 bounding_box=[0.5, 0.5, 0.4, 0.4],766 mask=instance1,767 ),768 ]769 ),770 polylines=fo.Polylines(771 polylines=[772 fo.Polyline(773 label="cat",774 points=[775 [776 (0.1, 0.1),777 (0.5, 0.1),778 (0.5, 0.5),779 (0.1, 0.5),780 ]781 ],782 filled=True,783 ),784 fo.Polyline(785 label="dog",786 points=[787 [788 (0.5, 0.5),789 (0.9, 0.5),790 (0.9, 0.9),791 (0.5, 0.9),792 ]793 ],794 filled=True,795 ),796 ]797 ),798 ),799 fo.Sample(filepath=self._new_image()),800 ]801 dataset = fo.Dataset()802 dataset.add_samples(samples)803 return dataset804 @drop_datasets805 def test_image_segmentation_directory(self):806 dataset = self._make_dataset()807 # Segmentations808 export_dir = self._new_dir()809 view = dataset.limit(2)810 view.export(811 export_dir=export_dir,812 dataset_type=fo.types.ImageSegmentationDirectory,813 label_field="segmentations",814 )815 dataset2 = fo.Dataset.from_dir(816 dataset_dir=export_dir,817 dataset_type=fo.types.ImageSegmentationDirectory,818 label_field="segmentations",819 )820 self.assertEqual(len(view), len(dataset2))821 self.assertEqual(822 view.count("segmentations.mask"),823 dataset2.count("segmentations.mask"),824 )825 # Detections826 export_dir = self._new_dir()827 view = dataset.limit(2)828 view.export(829 export_dir=export_dir,830 dataset_type=fo.types.ImageSegmentationDirectory,831 label_field="detections",832 )833 dataset2 = fo.Dataset.from_dir(834 dataset_dir=export_dir,835 dataset_type=fo.types.ImageSegmentationDirectory,836 label_field="segmentations",837 )838 self.assertEqual(len(view), len(dataset2))839 self.assertEqual(840 len(view.exists("detections")),841 len(dataset2.exists("segmentations")),842 )843 # Polylines844 export_dir = self._new_dir()845 view = dataset.limit(2)846 view.export(847 export_dir=export_dir,848 dataset_type=fo.types.ImageSegmentationDirectory,849 label_field="polylines",850 )851 dataset2 = fo.Dataset.from_dir(852 dataset_dir=export_dir,853 dataset_type=fo.types.ImageSegmentationDirectory,854 label_field="segmentations",855 )856 self.assertEqual(len(view), len(dataset2))857 self.assertEqual(858 len(view.exists("polylines")),859 len(dataset2.exists("segmentations")),860 )861 # Labels-only862 data_path = self.images_dir863 labels_path = os.path.join(self._new_dir(), "labels/")864 dataset.export(865 dataset_type=fo.types.ImageSegmentationDirectory,866 labels_path=labels_path,867 label_field="segmentations",868 )869 dataset2 = fo.Dataset.from_dir(870 dataset_type=fo.types.ImageSegmentationDirectory,871 data_path=data_path,872 labels_path=labels_path,873 label_field="segmentations",874 include_all_data=True,875 )876 self.assertEqual(len(dataset), len(dataset2))877 self.assertSetEqual(878 set(dataset.values("filepath")), set(dataset2.values("filepath")),879 )880 self.assertEqual(881 dataset.count("segmentations.mask"),882 dataset2.count("segmentations.mask"),883 )884class DICOMDatasetTests(ImageDatasetTests):885 def _get_dcm_path(self):886 import pydicom887 from pydicom.data import get_testdata_file888 return get_testdata_file("MR_small.dcm")889 @drop_datasets890 def test_dicom_dataset(self):891 dataset_dir = self._new_dir()892 images_dir = self._new_dir()893 ref_path = self._get_dcm_path()894 dicom_path = os.path.join(dataset_dir, "test.dcm")895 etau.copy_file(ref_path, dicom_path)896 # Standard format897 dataset = fo.Dataset.from_dir(898 dataset_dir=dataset_dir,899 images_dir=images_dir,900 dataset_type=fo.types.DICOMDataset,901 )902 self.assertEqual(len(dataset), 1)903 self.assertIn("PatientName", dataset.get_field_schema())904 # Direct path, specific keywords905 dataset2 = fo.Dataset.from_dir(906 dicom_path=dicom_path,907 images_dir=images_dir,908 dataset_type=fo.types.DICOMDataset,909 keywords=["PatientName"],910 )911 self.assertEqual(len(dataset2), 1)912 self.assertIn("PatientName", dataset2.get_field_schema())913class GeoLocationDatasetTests(ImageDatasetTests):914 def _make_dataset(self):915 samples = [916 fo.Sample(917 filepath=self._new_image(),918 coordinates=fo.GeoLocation(919 point=[-73.77615468583421, 40.76392586346787],920 ),921 weather=fo.Classification(label="sunny"),922 ),923 fo.Sample(924 filepath=self._new_image(),925 coordinates=fo.GeoLocation(926 point=[-74.00767702771716, 40.72345200411182],927 ),928 weather=fo.Classification(label="cloudy"),929 ),930 # @todo test with missing data; this currently may fail since931 # `add_samples()` does not graefully handle expanding the schema932 # to handle None-valued fields933 # fo.Sample(filepath=self._new_image()),934 ]935 dataset = fo.Dataset()936 dataset.add_samples(samples)937 return dataset938 @drop_datasets939 def test_geojson_dataset(self):940 dataset = self._make_dataset()941 # Standard format942 export_dir = self._new_dir()943 def maker(label):944 return label.label if label is not None else None945 dataset.export(946 export_dir=export_dir,947 dataset_type=fo.types.GeoJSONDataset,948 property_makers={"weather": maker},949 )950 def parser(value):951 return (952 fo.Classification(label=value) if value is not None else None953 )954 dataset2 = fo.Dataset.from_dir(955 dataset_dir=export_dir,956 dataset_type=fo.types.GeoJSONDataset,957 location_field="coordinates",958 property_parsers={"weather": parser},959 )960 self.assertEqual(len(dataset), len(dataset2))961 self.assertEqual(962 dataset.count("coordinates"), dataset2.count("coordinates")963 )964 self.assertEqual(dataset.count("weather"), dataset2.count("weather"))965 # Labels-only966 data_path = self.images_dir967 labels_path = os.path.join(self._new_dir(), "labels.json")968 dataset.export(969 labels_path=labels_path, dataset_type=fo.types.GeoJSONDataset,970 )971 dataset2 = fo.Dataset.from_dir(972 data_path=data_path,973 labels_path=labels_path,974 dataset_type=fo.types.GeoJSONDataset,975 location_field="coordinates",976 )977 self.assertEqual(len(dataset), len(dataset2))978 self.assertSetEqual(979 set(dataset.values("filepath")), set(dataset2.values("filepath")),980 )981 self.assertEqual(982 dataset.count("coordinates"), dataset2.count("coordinates")983 )984skipwindows = pytest.mark.skipif(985 os.name == "nt", reason="Windows hangs in workflows, fix me"986)987class MultitaskImageDatasetTests(ImageDatasetTests):988 def _make_dataset(self):989 samples = [990 fo.Sample(991 filepath=self._new_image(),992 weather=fo.Classification(label="sunny", confidence=0.9),993 predictions=fo.Detections(994 detections=[995 fo.Detection(996 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],997 ),998 fo.Detection(999 label="dog", bounding_box=[0.5, 0.5, 0.4, 0.4],1000 ),1001 ]1002 ),1003 ),1004 fo.Sample(1005 filepath=self._new_image(),1006 weather=fo.Classification(label="cloudy", confidence=0.95),1007 predictions=fo.Detections(1008 detections=[1009 fo.Detection(1010 label="cat",1011 bounding_box=[0.1, 0.1, 0.4, 0.4],1012 confidence=0.9,1013 age=51,1014 cute=True,1015 mood="surly",1016 ),1017 fo.Detection(1018 label="dog",1019 bounding_box=[0.5, 0.5, 0.4, 0.4],1020 confidence=0.95,1021 age=52,1022 cute=False,1023 mood="derpy",1024 ),1025 ]1026 ),1027 ),1028 fo.Sample(filepath=self._new_image()),1029 ]1030 dataset = fo.Dataset()1031 dataset.add_samples(samples)1032 return dataset1033 @drop_datasets1034 def test_fiftyone_image_labels_dataset(self):1035 dataset = self._make_dataset()1036 # Standard format1037 export_dir = self._new_dir()1038 dataset.export(1039 export_dir=export_dir,1040 dataset_type=fo.types.FiftyOneImageLabelsDataset,1041 )1042 dataset2 = fo.Dataset.from_dir(1043 dataset_dir=export_dir,1044 dataset_type=fo.types.FiftyOneImageLabelsDataset,1045 )1046 self.assertEqual(len(dataset), len(dataset2))1047 self.assertEqual(1048 dataset.count("weather"), dataset2.count("attributes"),1049 )1050 self.assertEqual(1051 dataset.distinct("weather.confidence"),1052 dataset2.distinct("attributes.confidence"),1053 )1054 self.assertEqual(1055 dataset.count("predictions.detections"),1056 dataset2.count("detections.detections"),1057 )1058 self.assertEqual(1059 dataset.distinct("predictions.detections.confidence"),1060 dataset2.distinct("detections.detections.confidence"),1061 )1062 @drop_datasets1063 def test_bdd_dataset(self):1064 dataset = self._make_dataset()1065 # Standard format1066 export_dir = self._new_dir()1067 view = dataset.limit(2)1068 view.export(1069 export_dir=export_dir, dataset_type=fo.types.BDDDataset,1070 )1071 dataset2 = fo.Dataset.from_dir(1072 dataset_dir=export_dir, dataset_type=fo.types.BDDDataset,1073 )1074 self.assertEqual(len(view), len(dataset2))1075 self.assertEqual(1076 view.count("weather"), dataset2.count("attributes"),1077 )1078 self.assertEqual(1079 view.count("predictions.detections"),1080 dataset2.count("detections.detections"),1081 )1082 # Handle unlabeled data1083 export_dir = self._new_dir()1084 dataset.export(1085 export_dir=export_dir, dataset_type=fo.types.BDDDataset,1086 )1087 dataset2 = fo.Dataset.from_dir(1088 dataset_dir=export_dir,1089 dataset_type=fo.types.BDDDataset,1090 include_all_data=True,1091 )1092 self.assertEqual(len(dataset), len(dataset2))1093 # Labels-only1094 data_path = self.images_dir1095 labels_path = os.path.join(self._new_dir(), "labels.json")1096 dataset.export(1097 labels_path=labels_path, dataset_type=fo.types.BDDDataset,1098 )1099 dataset2 = fo.Dataset.from_dir(1100 data_path=data_path,1101 labels_path=labels_path,1102 dataset_type=fo.types.BDDDataset,1103 include_all_data=True,1104 )1105 self.assertEqual(len(dataset), len(dataset2))1106 self.assertEqual(1107 dataset.count("weather"), dataset2.count("attributes"),1108 )1109 self.assertEqual(1110 dataset.count("predictions.detections"),1111 dataset2.count("detections.detections"),1112 )1113 @drop_datasets1114 def test_cvat_image_dataset(self):1115 dataset = self._make_dataset()1116 # Standard format1117 export_dir = self._new_dir()1118 view = dataset.limit(2)1119 view.export(1120 export_dir=export_dir, dataset_type=fo.types.CVATImageDataset,1121 )1122 dataset2 = fo.Dataset.from_dir(1123 dataset_dir=export_dir, dataset_type=fo.types.CVATImageDataset,1124 )1125 self.assertEqual(len(view), len(dataset2))1126 self.assertEqual(1127 view.count("predictions.detections"),1128 dataset2.count("detections.detections"),1129 )1130 # Handle unlabeled data1131 export_dir = self._new_dir()1132 dataset.export(1133 export_dir=export_dir, dataset_type=fo.types.CVATImageDataset,1134 )1135 dataset2 = fo.Dataset.from_dir(1136 dataset_dir=export_dir,1137 dataset_type=fo.types.CVATImageDataset,1138 include_all_data=True,1139 )1140 self.assertEqual(len(dataset), len(dataset2))1141 # Labels-only1142 data_path = self.images_dir1143 labels_path = os.path.join(self._new_dir(), "labels.xml")1144 dataset.export(1145 labels_path=labels_path, dataset_type=fo.types.CVATImageDataset,1146 )1147 dataset2 = fo.Dataset.from_dir(1148 data_path=data_path,1149 labels_path=labels_path,1150 dataset_type=fo.types.CVATImageDataset,1151 include_all_data=True,1152 )1153 self.assertEqual(len(dataset), len(dataset2))1154 self.assertEqual(1155 dataset.count("predictions.detections"),1156 dataset2.count("detections.detections"),1157 )1158 @skipwindows1159 @drop_datasets1160 def test_fiftyone_dataset(self):1161 dataset = self._make_dataset()1162 # Standard format1163 export_dir = self._new_dir()1164 dataset.export(1165 export_dir=export_dir, dataset_type=fo.types.FiftyOneDataset,1166 )1167 dataset2 = fo.Dataset.from_dir(1168 dataset_dir=export_dir, dataset_type=fo.types.FiftyOneDataset,1169 )1170 self.assertEqual(len(dataset), len(dataset2))1171 self.assertListEqual(1172 [os.path.basename(f) for f in dataset.values("filepath")],1173 [os.path.basename(f) for f in dataset2.values("filepath")],1174 )1175 self.assertListEqual(1176 dataset.values("weather.label"), dataset2.values("weather.label")1177 )1178 self.assertEqual(1179 dataset.count("predictions.detections"),1180 dataset2.count("predictions.detections"),1181 )1182class VideoDatasetTests(unittest.TestCase):1183 def setUp(self):1184 temp_dir = etau.TempDir()1185 tmp_dir = temp_dir.__enter__()1186 ref_video_path = os.path.join(tmp_dir, "_ref_video.mp4")1187 videos_dir = os.path.join(tmp_dir, "_videos")1188 with etav.FFmpegVideoWriter(ref_video_path, 5, (640, 480)) as writer:1189 for _ in range(5):1190 img = np.random.randint(1191 255, size=(480, 640, 3), dtype=np.uint81192 )1193 writer.write(img)1194 self._temp_dir = temp_dir1195 self._tmp_dir = tmp_dir1196 self._ref_video_path = ref_video_path1197 self.videos_dir = videos_dir1198 def tearDown(self):1199 self._temp_dir.__exit__()1200 def _new_video(self):1201 filepath = os.path.join(1202 self.videos_dir,1203 self._new_name() + os.path.splitext(self._ref_video_path)[1],1204 )1205 etau.copy_file(self._ref_video_path, filepath)1206 return filepath1207 def _new_name(self):1208 return "".join(1209 random.choice(string.ascii_lowercase + string.digits)1210 for _ in range(24)1211 )1212 def _new_dir(self):1213 return os.path.join(self._tmp_dir, self._new_name())1214class UnlabeledVideoDatasetTests(VideoDatasetTests):1215 def _make_dataset(self):1216 samples = [fo.Sample(filepath=self._new_video()) for _ in range(5)]1217 dataset = fo.Dataset()1218 dataset.add_samples(samples)1219 return dataset1220 @drop_datasets1221 def test_video_directory(self):1222 dataset = self._make_dataset()1223 export_dir = self._new_dir()1224 dataset.export(1225 export_dir=export_dir, dataset_type=fo.types.VideoDirectory,1226 )1227 dataset2 = fo.Dataset.from_dir(1228 dataset_dir=export_dir, dataset_type=fo.types.VideoDirectory,1229 )1230 self.assertEqual(len(dataset), len(dataset2))1231class VideoClassificationDatasetTests(VideoDatasetTests):1232 def _make_dataset(self):1233 samples = [1234 fo.Sample(1235 filepath=self._new_video(),1236 predictions=fo.Classification(label="cat", confidence=0.9),1237 ),1238 fo.Sample(1239 filepath=self._new_video(),1240 predictions=fo.Classification(label="dog", confidence=0.95),1241 ),1242 fo.Sample(filepath=self._new_video()),1243 ]1244 dataset = fo.Dataset()1245 dataset.add_samples(samples)1246 return dataset1247 @drop_datasets1248 def test_video_classification_directory_tree(self):1249 dataset = self._make_dataset()1250 # Standard format1251 export_dir = self._new_dir()1252 dataset.export(1253 export_dir=export_dir,1254 dataset_type=fo.types.VideoClassificationDirectoryTree,1255 )1256 dataset2 = fo.Dataset.from_dir(1257 dataset_dir=export_dir,1258 dataset_type=fo.types.VideoClassificationDirectoryTree,1259 label_field="predictions",1260 )1261 self.assertEqual(len(dataset), len(dataset2))1262 self.assertEqual(1263 dataset.count("predictions"), dataset2.count("predictions")1264 )1265class TemporalVideoClassificationDatasetTests(VideoDatasetTests):1266 def _make_dataset(self):1267 samples = [1268 fo.Sample(1269 filepath=self._new_video(),1270 predictions=fo.VideoClassifications(1271 classifications=[1272 fo.VideoClassification(1273 label="cat", support=[1, 3], confidence=0.91274 )1275 ]1276 ),1277 ),1278 fo.Sample(1279 filepath=self._new_video(),1280 predictions=fo.VideoClassifications(1281 classifications=[1282 fo.VideoClassification(1283 label="cat", support=[1, 4], confidence=0.95,1284 ),1285 fo.VideoClassification(1286 label="dog", support=[2, 5], confidence=0.95,1287 ),1288 ]1289 ),1290 ),1291 fo.Sample(filepath=self._new_video()),1292 ]1293 dataset = fo.Dataset()1294 dataset.add_samples(samples)1295 return dataset1296 @drop_datasets1297 def test_fiftyone_video_classification_dataset(self):1298 dataset = self._make_dataset()1299 # Standard format1300 export_dir = self._new_dir()1301 dataset.export(1302 export_dir=export_dir,1303 dataset_type=fo.types.FiftyOneVideoClassificationDataset,1304 )1305 dataset2 = fo.Dataset.from_dir(1306 dataset_dir=export_dir,1307 dataset_type=fo.types.FiftyOneVideoClassificationDataset,1308 label_field="predictions",1309 )1310 supports = dataset.values("predictions.classifications.support")1311 supports2 = dataset2.values("predictions.classifications.support")1312 self.assertEqual(len(dataset), len(dataset2))1313 # sorting is necessary because sample order is arbitrary1314 self.assertListEqual(1315 sorted(supports, key=lambda k: (k is None, k)),1316 sorted(supports2, key=lambda k: (k is None, k)),1317 )1318 # Use timestamps1319 export_dir = self._new_dir()1320 dataset.export(1321 export_dir=export_dir,1322 dataset_type=fo.types.FiftyOneVideoClassificationDataset,1323 use_timestamps=True,1324 )1325 dataset2 = fo.Dataset.from_dir(1326 dataset_dir=export_dir,1327 dataset_type=fo.types.FiftyOneVideoClassificationDataset,1328 label_field="predictions",1329 )1330 supports = dataset.values("predictions.classifications.support")1331 supports2 = dataset2.values("predictions.classifications.support")1332 self.assertEqual(len(dataset), len(dataset2))1333 # sorting is necessary because sample order is arbitrary1334 self.assertListEqual(1335 sorted(supports, key=lambda k: (k is None, k)),1336 sorted(supports2, key=lambda k: (k is None, k)),1337 )1338class MultitaskVideoDatasetTests(VideoDatasetTests):1339 def _make_dataset(self):1340 sample1 = fo.Sample(filepath=self._new_video())1341 sample1.frames[1] = fo.Frame(1342 weather=fo.Classification(label="sunny", confidence=0.9),1343 predictions=fo.Detections(1344 detections=[1345 fo.Detection(1346 label="cat", bounding_box=[0.1, 0.1, 0.4, 0.4],1347 ),1348 fo.Detection(1349 label="dog", bounding_box=[0.5, 0.5, 0.4, 0.4],1350 ),1351 ]1352 ),1353 )1354 sample1.frames[2] = fo.Frame(1355 weather=fo.Classification(label="cloudy", confidence=0.95),1356 predictions=fo.Detections(1357 detections=[1358 fo.Detection(1359 label="cat",1360 bounding_box=[0.1, 0.1, 0.4, 0.4],1361 confidence=0.9,1362 age=51,1363 cute=True,1364 mood="surly",1365 ),1366 fo.Detection(1367 label="dog",1368 bounding_box=[0.5, 0.5, 0.4, 0.4],1369 confidence=0.95,1370 age=52,1371 cute=False,1372 mood="derpy",1373 ),1374 ]1375 ),1376 )1377 sample2 = fo.Sample(filepath=self._new_video())1378 sample2.frames[1] = fo.Frame()1379 sample3 = fo.Sample(filepath=self._new_video())1380 dataset = fo.Dataset()1381 dataset.add_samples([sample1, sample2, sample3])1382 return dataset1383 @drop_datasets1384 def test_fiftyone_video_labels_dataset(self):1385 dataset = self._make_dataset()1386 # Standard format1387 export_dir = self._new_dir()1388 dataset.export(1389 export_dir=export_dir,1390 dataset_type=fo.types.FiftyOneVideoLabelsDataset,1391 )1392 dataset2 = fo.Dataset.from_dir(1393 dataset_dir=export_dir,1394 dataset_type=fo.types.FiftyOneVideoLabelsDataset,1395 )1396 self.assertEqual(len(dataset), len(dataset2))1397 self.assertEqual(1398 dataset.count("frames.weather"),1399 dataset2.count("frames.attributes"),1400 )1401 self.assertEqual(1402 dataset.distinct("frames.weather.confidence"),1403 dataset2.distinct("frames.attributes.confidence"),1404 )1405 self.assertEqual(1406 dataset.count("frames.predictions.detections"),1407 dataset2.count("frames.detections.detections"),1408 )1409 self.assertEqual(1410 dataset.distinct("frames.predictions.detections.confidence"),1411 dataset2.distinct("frames.detections.detections.confidence"),1412 )1413 @drop_datasets1414 def test_cvat_video_dataset(self):1415 dataset = self._make_dataset()1416 # Standard format1417 export_dir = self._new_dir()1418 view = dataset.limit(1)1419 view.export(1420 export_dir=export_dir, dataset_type=fo.types.CVATVideoDataset,1421 )1422 dataset2 = fo.Dataset.from_dir(1423 dataset_dir=export_dir, dataset_type=fo.types.CVATVideoDataset,1424 )1425 self.assertEqual(len(view), len(dataset2))1426 self.assertEqual(1427 view.count("frames.predictions.detections"),1428 dataset2.count("frames.detections.detections"),1429 )1430 # Handle unlabeled data1431 export_dir = self._new_dir()1432 dataset.export(1433 export_dir=export_dir, dataset_type=fo.types.CVATVideoDataset,1434 )1435 dataset2 = fo.Dataset.from_dir(1436 dataset_dir=export_dir,1437 dataset_type=fo.types.CVATVideoDataset,1438 include_all_data=True,1439 )1440 self.assertEqual(len(dataset), len(dataset2))1441 # Labels-only1442 data_path = self.videos_dir1443 labels_path = os.path.join(self._new_dir(), "labels/")1444 dataset.export(1445 labels_path=labels_path, dataset_type=fo.types.CVATVideoDataset,1446 )1447 dataset2 = fo.Dataset.from_dir(1448 data_path=data_path,1449 labels_path=labels_path,1450 dataset_type=fo.types.CVATVideoDataset,1451 include_all_data=True,1452 )1453 self.assertEqual(len(dataset), len(dataset2))1454 self.assertEqual(1455 dataset.count("frames.predictions.detections"),1456 dataset2.count("frames.detections.detections"),1457 )...
open_scripts.py
Source:open_scripts.py
1import os2import sys3from typing import List4from pathlib import Path5import shutil6import platform7import subprocess8SHELL = platform.system() == 'Windows'9def open_dir(path):10 if platform.system() == "Windows":11 os.startfile(path)12 elif platform.system() == "Darwin":13 subprocess.call(["open", str(path)])14 elif platform.system() == "Linux":15 subprocess.call(["gnome-terminal", f"--working-directory={path}"])16class OpenScript:17 TEMP_FOLDER = "temp_{sid}"18 19 def __init__(self, sid, submission_path, support_code, ide, *args,20 keep_temp=False):21 self._sid = sid22 self._submission_path = submission_path23 self._support_code_path = support_code24 self._keep_temp = keep_temp25 self._to_open: List[str] = list(str(arg) for arg in args)26 self._to_run = str(args[0])27 self._ide = ide28 self._new_dir: Path = None29 self.create_marking_dir()30 31 def create_marking_dir(self):32 if self._keep_temp:33 self._new_dir = self.TEMP_FOLDER.format(sid=self._sid)34 else:35 self._new_dir = "temp_marking"36 self._new_dir = Path(self._new_dir)37 if self._new_dir.is_dir():38 shutil.rmtree(self._new_dir)39 self._new_dir.mkdir()40 # for root, dir, file in os.walk(self._support_code_path):41 # pass42 43 shutil.copytree(self._support_code_path, self._new_dir, dirs_exist_ok=True)44 shutil.copytree(self._submission_path, self._new_dir, dirs_exist_ok=True)45 46 def open_scripts(self):47 open_dir(self._new_dir.resolve())48 to_opens = []49 for to_open in self._to_open:50 if not (self._new_dir.resolve() / to_open).exists():51 continue52 to_opens.append(to_open)53 # if len(to_opens) != len(self._to_open):54 # print("Missing files:")55 # for missing in self._to_open:56 # if missing in to_opens:57 # continue58 # print(f"\t{missing}")59 subprocess.call([self._ide, '-n', '-w'] +60 [self._new_dir.resolve() / to_open for61 to_open in to_opens],62 shell=SHELL)63 64 def run_script(self):65 subprocess.call([sys.executable, self._new_dir.resolve() / self._to_run],66 cwd=self._new_dir.resolve())67 def open_scripts_in_idle(self):68 subprocess.call([sys.executable,69 "-m",70 "idlelib",71 self._new_dir.resolve() / self._to_run],72 cwd=self._new_dir.resolve())73 74 def get_marking_folder(self):75 return self._new_dir76 77if __name__ == '__main__':...
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!!