""" Testing ======= General guidelines for writing good tests: - doctests always assume ``import networkx as nx`` so don't add that - prefer pytest fixtures over classes with setup methods. - use the ``@pytest.mark.parametrize`` decorator - use ``pytest.importorskip`` for numpy, scipy, pandas, and matplotlib b/c of PyPy. and add the module to the relevant entries below. """ import sys import warnings import pytest import networkx def pytest_addoption(parser): parser.addoption( "--runslow", action="store_true", default=False, help="run slow tests" ) def pytest_configure(config): config.addinivalue_line("markers", "slow: mark test as slow to run") def pytest_collection_modifyitems(config, items): if config.getoption("--runslow"): # --runslow given in cli: do not skip slow tests return skip_slow = pytest.mark.skip(reason="need --runslow option to run") for item in items: if "slow" in item.keywords: item.add_marker(skip_slow) # TODO: The warnings below need to be dealt with, but for now we silence them. @pytest.fixture(autouse=True) def set_warnings(): warnings.filterwarnings( "ignore", category=DeprecationWarning, message="k_nearest_neighbors" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="numeric_mixing_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message=r"Ordered.* is deprecated" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="literal_stringizer is deprecated", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="literal_destringizer is deprecated", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="is_string_like is deprecated" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\nauthority_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\nhub_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="default_opener is deprecated" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="empty_generator is deprecated" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="make_str is deprecated" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="generate_unique_node is deprecated", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="context manager reversed is deprecated", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="This will return a generator in 3.0*", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="betweenness_centrality_source" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="edge_betweeness" ) warnings.filterwarnings( "ignore", category=PendingDeprecationWarning, message="the matrix subclass" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="to_numpy_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="from_numpy_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="networkx.pagerank_numpy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="networkx.pagerank_scipy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="write_gpickle" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="read_gpickle" ) warnings.filterwarnings("ignore", category=DeprecationWarning, message="write_shp") warnings.filterwarnings("ignore", category=DeprecationWarning, message="read_shp") warnings.filterwarnings( "ignore", category=DeprecationWarning, message="edges_from_line" ) warnings.filterwarnings("ignore", category=DeprecationWarning, message="write_yaml") warnings.filterwarnings("ignore", category=DeprecationWarning, message="read_yaml") warnings.filterwarnings( "ignore", category=DeprecationWarning, message="FilterAtlas.copy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="FilterAdjacency.copy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="FilterMultiAdjacency.copy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="FilterMultiInner.copy" ) warnings.filterwarnings("ignore", category=DeprecationWarning, message="jit_data") warnings.filterwarnings("ignore", category=DeprecationWarning, message="jit_graph") warnings.filterwarnings("ignore", category=DeprecationWarning, message="consume") warnings.filterwarnings( "ignore", category=DeprecationWarning, message="iterable is deprecated" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="\nThe function signature for cytoscape", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\nThe `attrs` keyword" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="preserve_random_state" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="`almost_equal`" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="`assert_nodes_equal`" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="`assert_edges_equal`" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="`assert_graphs_equal`" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="networkx.hits_scipy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="networkx.hits_numpy" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="preserve_random_state" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="google_matrix will return an np.ndarray instead of a np.matrix", ) ### Future warnings from scipy.sparse array transition warnings.filterwarnings( "ignore", category=FutureWarning, message="biadjacency_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="bethe_hessian_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="incidence_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="laplacian_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="normalized_laplacian_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="directed_laplacian_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="directed_combinatorial_laplacian_matrix", ) warnings.filterwarnings( "ignore", category=FutureWarning, message="modularity_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="directed_modularity_matrix" ) warnings.filterwarnings( "ignore", category=FutureWarning, message="adjacency_matrix" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\n\nThe scipy.sparse array containers", ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="networkx.project" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\nfind_cores" ) warnings.filterwarnings("ignore", category=FutureWarning, message="attr_matrix") warnings.filterwarnings( "ignore", category=DeprecationWarning, message=r"\n\nmake_small_.*" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="to_numpy_recarray" ) warnings.filterwarnings("ignore", category=DeprecationWarning, message="info") warnings.filterwarnings("ignore", category=DeprecationWarning, message="to_tuple") # create_using for scale_free_graph warnings.filterwarnings( "ignore", category=DeprecationWarning, message="The create_using argument" ) warnings.filterwarnings( "ignore", category=PendingDeprecationWarning, message="nx.nx_pydot" ) warnings.filterwarnings( "ignore", category=DeprecationWarning, message="\n\nThe `attrs` keyword argument of node_link", ) @pytest.fixture(autouse=True) def add_nx(doctest_namespace): doctest_namespace["nx"] = networkx # What dependencies are installed? try: import numpy has_numpy = True except ImportError: has_numpy = False try: import scipy has_scipy = True except ImportError: has_scipy = False try: import matplotlib has_matplotlib = True except ImportError: has_matplotlib = False try: import pandas has_pandas = True except ImportError: has_pandas = False try: import pygraphviz has_pygraphviz = True except ImportError: has_pygraphviz = False try: import yaml has_yaml = True except ImportError: has_yaml = False try: import pydot has_pydot = True except ImportError: has_pydot = False try: import ogr has_ogr = True except ImportError: has_ogr = False try: import sympy has_sympy = True except ImportError: has_sympy = False # List of files that pytest should ignore collect_ignore = [] needs_numpy = [ "algorithms/approximation/traveling_salesman.py", "algorithms/centrality/current_flow_closeness.py", "algorithms/node_classification/__init__.py", "algorithms/non_randomness.py", "algorithms/shortest_paths/dense.py", "linalg/bethehessianmatrix.py", "linalg/laplacianmatrix.py", "utils/misc.py", ] needs_scipy = [ "algorithms/approximation/traveling_salesman.py", "algorithms/assortativity/correlation.py", "algorithms/assortativity/mixing.py", "algorithms/assortativity/pairs.py", "algorithms/bipartite/matrix.py", "algorithms/bipartite/spectral.py", "algorithms/centrality/current_flow_betweenness.py", "algorithms/centrality/current_flow_betweenness_subset.py", "algorithms/centrality/eigenvector.py", "algorithms/centrality/katz.py", "algorithms/centrality/second_order.py", "algorithms/centrality/subgraph_alg.py", "algorithms/communicability_alg.py", "algorithms/link_analysis/hits_alg.py", "algorithms/link_analysis/pagerank_alg.py", "algorithms/node_classification/__init__.py", "algorithms/node_classification/hmn.py", "algorithms/node_classification/lgc.py", "algorithms/similarity.py", "convert_matrix.py", "drawing/layout.py", "generators/spectral_graph_forge.py", "linalg/algebraicconnectivity.py", "linalg/attrmatrix.py", "linalg/bethehessianmatrix.py", "linalg/graphmatrix.py", "linalg/modularitymatrix.py", "linalg/spectrum.py", "utils/rcm.py", ] needs_matplotlib = ["drawing/nx_pylab.py"] needs_pandas = ["convert_matrix.py"] needs_yaml = ["readwrite/nx_yaml.py"] needs_pygraphviz = ["drawing/nx_agraph.py"] needs_pydot = ["drawing/nx_pydot.py"] needs_ogr = ["readwrite/nx_shp.py"] needs_sympy = ["algorithms/polynomials.py"] if not has_numpy: collect_ignore += needs_numpy if not has_scipy: collect_ignore += needs_scipy if not has_matplotlib: collect_ignore += needs_matplotlib if not has_pandas: collect_ignore += needs_pandas if not has_yaml: collect_ignore += needs_yaml if not has_pygraphviz: collect_ignore += needs_pygraphviz if not has_pydot: collect_ignore += needs_pydot if not has_ogr: collect_ignore += needs_ogr if not has_sympy: collect_ignore += needs_sympy