Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test fixtures #4241

Merged
merged 17 commits into from
Mar 12, 2022
5 changes: 4 additions & 1 deletion .github/workflows/full_testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ on: # yamllint disable-line rule:truthy
jobs:

pytest:
if: github.repository == 'pyg-team/pytorch_geometric'
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: [3.7, 3.9]
python-version: [3.7, 3.8, 3.9, 3.10]
torch-version: [1.10.0]
include:
- torch-version: 1.10.0
Expand Down Expand Up @@ -44,6 +45,8 @@ jobs:
- name: Run tests
run: |
FULL_TEST=1 pytest --cov --cov-report=xml
shell:
bash

- name: Upload coverage
uses: codecov/codecov-action@v2
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: [3.7, 3.9]
os: [ubuntu-latest]
python-version: [3.9]
torch-version: [1.10.0, 1.11.0]
include:
- torch-version: 1.10.0
Expand Down
12 changes: 11 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,22 @@ Everytime you send a Pull Request, your commit will be built and checked against

If you do not want to format your code manually, we recommend to use [`yapf`](https://github.com/google/yapf).

2. Ensure that the entire test suite passes and that code coverage roughly stays the same. Please feel encouraged to provide a test with your submitted code.
2. Ensure that the entire test suite passes and that code coverage roughly stays the same.
Please feel encouraged to provide a test with your submitted code.
To test, either run

```bash
pytest --cov
```

or

```bash
FULL_TEST=1 pytest --cov
```

(which runs a set of additional but time-consuming tests) dependening on your needs.

## Building Documentation

To build the documentation:
Expand Down
47 changes: 47 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import functools
import os.path as osp
import shutil

import pytest

from torch_geometric.data import Dataset


def load_dataset(root: str, name: str, *args, **kwargs) -> Dataset:
r"""Returns a variety of datasets according to :obj:`name`."""
if 'karate' in name.lower():
from torch_geometric.datasets import KarateClub
return KarateClub(*args, **kwargs)
if name.lower() in ['cora', 'citeseer', 'pubmed']:
from torch_geometric.datasets import Planetoid
path = osp.join(root, 'Planetoid', name)
return Planetoid(path, name, *args, **kwargs)
if name in ['BZR', 'ENZYMES', 'IMDB-BINARY', 'MUTAG']:
from torch_geometric.datasets import TUDataset
path = osp.join(root, 'TUDataset')
return TUDataset(path, name, *args, **kwargs)
if name in ['ego-facebook', 'soc-Slashdot0811', 'wiki-vote']:
from torch_geometric.datasets import SNAPDataset
path = osp.join(root, 'SNAPDataset')
return SNAPDataset(path, name, *args, **kwargs)
if name.lower() in ['bashapes']:
from torch_geometric.datasets import BAShapes
return BAShapes(*args, **kwargs)
if name.lower() in ['dblp']:
from torch_geometric.datasets import DBLP
path = osp.join(root, 'DBLP')
return DBLP(path, *args, **kwargs)
if name in ['citationCiteseer', 'illc1850']:
from torch_geometric.datasets import SuiteSparseMatrixCollection
path = osp.join(root, 'SuiteSparseMatrixCollection')
return SuiteSparseMatrixCollection(path, name=name, *args, **kwargs)

raise NotImplementedError


@pytest.fixture(scope='session')
def get_dataset():
root = osp.join('/', 'tmp', 'pyg_test_datasets')
yield functools.partial(load_dataset, root)
if osp.exists(root):
shutil.rmtree(root)
23 changes: 6 additions & 17 deletions test/data/test_lightning_datamodule.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import math
import os.path as osp
import random
import shutil
import sys
import warnings

import pytest
import torch
import torch.nn.functional as F

from torch_geometric.data import LightningDataset, LightningNodeData
from torch_geometric.datasets import DBLP, Planetoid, TUDataset
from torch_geometric.nn import global_mean_pool

try:
Expand Down Expand Up @@ -61,15 +56,13 @@ def configure_optimizers(self):
@pytest.mark.skipif(no_pytorch_lightning, reason='PL not available')
@pytest.mark.skipif(not torch.cuda.is_available(), reason='CUDA not available')
@pytest.mark.parametrize('strategy', [None, 'ddp_spawn'])
def test_lightning_dataset(strategy):
def test_lightning_dataset(get_dataset, strategy):
import pytorch_lightning as pl

root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, name='MUTAG').shuffle()
dataset = get_dataset(name='MUTAG').shuffle()
train_dataset = dataset[:50]
val_dataset = dataset[50:80]
test_dataset = dataset[80:90]
shutil.rmtree(root)

gpus = 1 if strategy is None else torch.cuda.device_count()
if strategy == 'ddp_spawn':
Expand Down Expand Up @@ -146,15 +139,13 @@ def configure_optimizers(self):
@pytest.mark.skipif(not torch.cuda.is_available(), reason='CUDA not available')
@pytest.mark.parametrize('loader', ['full', 'neighbor'])
@pytest.mark.parametrize('strategy', [None, 'ddp_spawn'])
def test_lightning_node_data(strategy, loader):
def test_lightning_node_data(get_dataset, strategy, loader):
import pytorch_lightning as pl

root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = Planetoid(root, name='Cora')
dataset = get_dataset(name='Cora')
data = dataset[0]
data_repr = ('Data(x=[2708, 1433], edge_index=[2, 10556], y=[2708], '
'train_mask=[2708], val_mask=[2708], test_mask=[2708])')
shutil.rmtree(root)

model = LinearNodeModule(dataset.num_features, dataset.num_classes)

Expand Down Expand Up @@ -237,13 +228,11 @@ def configure_optimizers(self):

@pytest.mark.skipif(no_pytorch_lightning, reason='PL not available')
@pytest.mark.skipif(not torch.cuda.is_available(), reason='CUDA not available')
def test_lightning_hetero_node_data():
def test_lightning_hetero_node_data(get_dataset):
import pytorch_lightning as pl

root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = DBLP(root)
dataset = get_dataset(name='DBLP')
data = dataset[0]
shutil.rmtree(root)

model = LinearHeteroNodeModule(data['author'].num_features,
int(data['author'].y.max()) + 1)
Expand Down
8 changes: 2 additions & 6 deletions test/datasets/test_ba_shapes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
from torch_geometric.datasets import BAShapes


def test_ba_shapes():
dataset = BAShapes()
def test_ba_shapes(get_dataset):
dataset = get_dataset(name='BAShapes')
assert str(dataset) == 'BAShapes()'

assert len(dataset) == 1
assert dataset.num_features == 10
assert dataset.num_classes == 4
Expand Down
23 changes: 9 additions & 14 deletions test/datasets/test_bzr.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import os.path as osp
import random
import shutil
import sys
from torch_geometric.testing import onlyFullTest

from torch_geometric.datasets import TUDataset


def test_bzr():
root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, 'BZR')

@onlyFullTest
def test_bzr(get_dataset):
dataset = get_dataset(name='BZR')
assert len(dataset) == 405
assert dataset.num_features == 53
assert dataset.num_node_labels == 53
assert dataset.num_node_attributes == 0
assert dataset.num_classes == 2
assert dataset.__repr__() == 'BZR(405)'
assert str(dataset) == 'BZR(405)'
assert len(dataset[0]) == 3

dataset = TUDataset(root, 'BZR', use_node_attr=True)

@onlyFullTest
def test_bzr_with_node_attr(get_dataset):
dataset = get_dataset(name='BZR', use_node_attr=True)
assert dataset.num_features == 56
assert dataset.num_node_labels == 53
assert dataset.num_node_attributes == 3

shutil.rmtree(root)
28 changes: 8 additions & 20 deletions test/datasets/test_enzymes.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
import os.path as osp
import random
import shutil
import sys

import pytest
import torch

from torch_geometric.datasets import TUDataset
from torch_geometric.loader import DataListLoader, DataLoader, DenseDataLoader
from torch_geometric.transforms import ToDense


def test_enzymes():
root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, 'ENZYMES')

def test_enzymes(get_dataset):
dataset = get_dataset(name='ENZYMES')
assert len(dataset) == 600
assert dataset.num_features == 3
assert dataset.num_classes == 6
assert dataset.__repr__() == 'ENZYMES(600)'
assert str(dataset) == 'ENZYMES(600)'

assert len(dataset[0]) == 3
assert len(dataset.shuffle()) == 600
Expand Down Expand Up @@ -63,18 +55,14 @@ def test_enzymes():
assert list(data.mask.size()) == [600, 126]
assert list(data.y.size()) == [600, 1]

dataset = TUDataset(root, 'ENZYMES', use_node_attr=True)

def test_enzymes_with_node_attr(get_dataset):
dataset = get_dataset(name='ENZYMES', use_node_attr=True)
assert dataset.num_node_features == 21
assert dataset.num_features == 21
assert dataset.num_edge_features == 0

shutil.rmtree(root)


def test_cleaned_enzymes():
root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, 'ENZYMES', cleaned=True)

def test_cleaned_enzymes(get_dataset):
dataset = get_dataset(name='ENZYMES', cleaned=True)
assert len(dataset) == 595

shutil.rmtree(root)
16 changes: 4 additions & 12 deletions test/datasets/test_imdb_binary.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import os.path as osp
import random
import shutil
import sys
from torch_geometric.testing import onlyFullTest

from torch_geometric.datasets import TUDataset


def test_imdb_binary():
root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, 'IMDB-BINARY')

@onlyFullTest
def test_imdb_binary(get_dataset):
dataset = get_dataset(name='IMDB-BINARY')
assert len(dataset) == 1000
assert dataset.num_features == 0
assert dataset.num_classes == 2
Expand All @@ -20,5 +14,3 @@ def test_imdb_binary():
assert data.edge_index.size() == (2, 146)
assert data.y.size() == (1, )
assert data.num_nodes == 20

shutil.rmtree(root)
10 changes: 3 additions & 7 deletions test/datasets/test_karate.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
from torch_geometric.datasets import KarateClub


def test_karate():
dataset = KarateClub()

def test_karate(get_dataset):
dataset = get_dataset(name='KarateClub')
assert str(dataset) == 'KarateClub()'
assert len(dataset) == 1
assert dataset.num_features == 34
assert dataset.num_classes == 4
assert dataset.__repr__() == 'KarateClub()'

assert len(dataset[0]) == 4
assert dataset[0].edge_index.size() == (2, 156)
Expand Down
22 changes: 6 additions & 16 deletions test/datasets/test_mutag.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
import os.path as osp
import random
import shutil
import sys

from torch_geometric.datasets import TUDataset


def test_mutag():
root = osp.join('/', 'tmp', str(random.randrange(sys.maxsize)))
dataset = TUDataset(root, 'MUTAG')

def test_mutag(get_dataset):
dataset = get_dataset(name='MUTAG')
assert len(dataset) == 188
assert dataset.num_features == 7
assert dataset.num_classes == 2
assert dataset.__repr__() == 'MUTAG(188)'
assert str(dataset) == 'MUTAG(188)'

assert len(dataset[0]) == 4
assert dataset[0].edge_attr.size(1) == 4

dataset = TUDataset(root, 'MUTAG', use_node_attr=True)
assert dataset.num_features == 7

shutil.rmtree(root)
def test_mutag_with_node_attr(get_dataset):
dataset = get_dataset(name='MUTAG', use_node_attr=True)
assert dataset.num_features == 7