@@ -430,295 +430,3 @@ Next, push your changes to the remote server, e.g.
430
430
When the feature is complete, create a *pull request * on GitHub so that the
431
431
changes can be merged back into the development branch. For information, see
432
432
the documentation `here <https://help.github.com/articles/about-pull-requests >`__.
433
-
434
- orkflow
435
- ========
436
-
437
- Feature branches
438
- ----------------
439
-
440
- First make sure that you are on the development branch of BioSimSpace:
441
-
442
- .. code-block :: bash
443
-
444
- git checkout devel
445
-
446
- Now create and switch to a feature branch. This should be prefixed with
447
- *feature *, e.g.
448
-
449
- .. code-block :: bash
450
-
451
- git checkout -b feature-process
452
-
453
- While working on your feature branch you won't want to continually re-install
454
- in order to make the changes active. To avoid this, you can either make use
455
- of ``PYTHONPATH ``, e.g.
456
-
457
- .. code-block :: bash
458
-
459
- PYTHONPATH=$HOME /Code/BioSimSpace/python python script.py
460
-
461
- or use the ``develop `` argument when running the ``setup.py `` script, i.e.
462
-
463
- .. code-block :: bash
464
-
465
- python setup.py develop
466
-
467
- Testing
468
- -------
469
-
470
- When working on your feature it is important to write tests to ensure that it
471
- does what is expected and doesn't break any existing functionality. Tests
472
- should be placed inside the ``test `` directory, creating an appropriately named
473
- sub-directory for any new packages.
474
-
475
- The test suite is intended to be run using `pytest <https://docs.pytest.org/en/latest/contents.html >`__.
476
- When run, ``pytest `` searches for tests in all directories and files below the current
477
- directory, collects the tests together, then runs them. Pytest uses name matching
478
- to locate the tests. Valid names start or end with *test *\ , e.g.:
479
-
480
- .. code-block :: python
481
-
482
- # Files:
483
- test_file.py file_test.py
484
-
485
- # Functions:
486
- def test_func (): def func_test ():
487
-
488
- We use the convention of ``test_* `` when naming files and functions.
489
-
490
- Running tests
491
- ^^^^^^^^^^^^^
492
-
493
- To run the full test suite, simply type:
494
-
495
- .. code-block :: bash
496
-
497
- pytest
498
-
499
- (This assumes that you have made the ``bin `` directory of your BioSimSpace or
500
- Sire installation available to your ``PATH ``.)
501
-
502
- To run tests for a specific sub-module, e.g.:
503
-
504
- .. code-block :: bash
505
-
506
- pytest test/Process
507
-
508
- To only run the unit tests in a particular file, e.g.:
509
-
510
- .. code-block :: bash
511
-
512
- pytest test/Process/test_namd.py
513
-
514
- To run a specific unit tests in a particular file, e.g.:
515
-
516
- .. code-block :: bash
517
-
518
- pytest test/Process/test_namd.py::test_minimise
519
-
520
- To get more detailed information about each test, run pytests using the
521
- *verbose * flag, e.g.:
522
-
523
- .. code-block :: bash
524
-
525
- pytest -v
526
-
527
- More details regarding how to invoke ``pytest `` can be found `here <https://docs.pytest.org/en/latest/usage.html >`__.
528
-
529
- Writing tests
530
- ^^^^^^^^^^^^^
531
-
532
- Basics
533
- """"""
534
-
535
- Try to keep individual unit tests short and clear. Aim to test one thing, and
536
- test it well. Where possible, try to minimise the use of ``assert `` statements
537
- within a unit test. Since the test will return on the first failed assertion,
538
- additional contextual information may be lost.
539
-
540
- Floating point comparisons
541
- """"""""""""""""""""""""""
542
-
543
- Make use of the `approx <https://docs.pytest.org/en/latest/builtin.html#comparing-floating-point-numbers >`__
544
- function from the ``pytest `` package for performing floating point comparisons, e.g:
545
-
546
- .. code-block :: python
547
-
548
- from pytest import approx
549
-
550
- assert 0.1 + 0.2 == approx(0.3 )
551
-
552
- By default, the ``approx `` function compares the result using a relative tolerance
553
- of 1e-6. This can be changed by passing a keyword argument to the function, e.g:
554
-
555
- .. code-block :: python
556
-
557
- assert 2 + 3 == approx(7 , rel = 2 )
558
-
559
- Skipping tests
560
- """"""""""""""
561
-
562
- If you are using `test-driven development <https://en.wikipedia.org/wiki/Test-driven_development >`__
563
- it might be desirable to write your tests before implementing the functionality,
564
- i.e. you are asserting what the *output * of a function should be, not how it should
565
- be *implemented *. In this case, you can make use of the ``pytest `` *skip * decorator
566
- to flag that a unit test should be skipped, e.g.:
567
-
568
- .. code-block :: python
569
-
570
- @pytest.mark.skip (reason = " Not yet implemented." )
571
- def test_new_feature ():
572
- # A unit test for an, as yet, unimplemented feature.
573
- ...
574
-
575
- Parametrizing tests
576
- """""""""""""""""""
577
-
578
- Often it is desirable to run a test for a range of different input parameters.
579
- This can be achieved using the ``parametrize `` decorator, e.g.:
580
-
581
- .. code-block :: python
582
-
583
- import pytest
584
- from operator import mul
585
-
586
- @pytest.mark.parametrize (" x" , [1 , 2 ])
587
- @pytest.mark.parametrize (" y" , [3 , 4 ])
588
- def test_mul (x , y ):
589
- """ Test the mul function. """
590
- assert mul(x, y) == mul(y, x)
591
-
592
- Here the function test_mul is parametrized with two parameters, ``x `` and ``y ``.
593
- By marking the test in this manner it will be executed using all possible
594
- parameter pairs ``(x, y) ``\ , i.e. ``(1, 3), (1, 4), (2, 3), (2, 4) ``.
595
-
596
- Alternatively:
597
-
598
- .. code-block :: python
599
-
600
- import pytest
601
- from operator import sub
602
- @pytest.mark.parametrize (" x, y, expected" ,
603
- [(1 , 2 , - 1 ),
604
- (7 , 3 , 4 ),
605
- (21 , 58 , - 37 )])
606
- def test_sub (x , y , expected ):
607
- """ Test the sub function. """
608
- assert sub(x, y) == - sub(y, x) == expected
609
-
610
- Here we are passing a list containing different parameter sets, with the names
611
- of the parameters matched against the arguments of the test function.
612
-
613
- Testing exceptions
614
- """"""""""""""""""
615
-
616
- Pytest provides a way of testing your code for known exceptions. For example,
617
- suppose we had a function that raises an ``IndexError ``\ :
618
-
619
- .. code-block :: python
620
-
621
- def indexError ():
622
- """ A function that raises an IndexError. """
623
- a = []
624
- a[3 ]
625
-
626
- We could then write a test to validate that the error is thrown as expected:
627
-
628
- .. code-block :: python
629
-
630
- def test_indexError ():
631
- with pytest.raises(IndexError ):
632
- indexError()
633
-
634
- Custom attributes
635
- """""""""""""""""
636
-
637
- It's possible to mark test functions with any attribute you like. For example:
638
-
639
- .. code-block :: python
640
-
641
- @pytest.mark.slow
642
- def test_slow_function ():
643
- """ A unit test that takes a really long time. """
644
- ...
645
-
646
- Here we have marked the test function with the attribute ``slow `` in order to
647
- indicate that it takes a while to run. From the command line it is possible
648
- to run or skip tests with a particular mark.
649
-
650
- .. code-block :: python
651
-
652
- pytest mypkg - m " slow" # only run the slow tests
653
- pytest mypkg - m " not slow" # skip the slow tests
654
-
655
- The custom attribute can just be a label, as in this case, or could be your
656
- own function decorator.
657
-
658
- Documentation
659
- -------------
660
-
661
- BioSimSpace is fully documented using `NumPy <https://numpy.org >`__ style
662
- docstrings. See `here <https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard >`__
663
- for details. The documentation is automatically built using
664
- `Sphinx <http://sphinx-doc.org >`__ whenever a commit is pushed to devel, which
665
- will then update this website.
666
-
667
- To build the documentation locally you will first need to install some
668
- additional packages.
669
-
670
- .. code-block :: bash
671
-
672
- pip install sphinx sphinx_issues sphinx_rtd_theme
673
-
674
- Then move to the ``doc `` directory and run:
675
-
676
- .. code-block :: bash
677
-
678
- sphinx-build make html
679
-
680
- When finished, point your browser to ``build/html/index.html ``.
681
-
682
- Committing
683
- ----------
684
-
685
- If you create new tests, please make sure that they pass locally before
686
- committing. When happy, commit your changes, e.g.
687
-
688
- .. code-block :: bash
689
-
690
- git commit python/BioSimSpace/Feature/new_feature.py test/Feature/test_feature \
691
- -m " Implementation and test for new feature."
692
-
693
- Remember that it is better to make small changes and commit frequently.
694
-
695
- If your edits don't change the BioSimSpace source code, or documentation,
696
- e.g. fixing typos, then please add ``ci skip `` to your commit message.
697
- This will avoid unnecessarily triggering
698
- `GitHub actions <https://github.com/openbiosim/biosimspace/actions?query=workflow%3ABuild >`__, e.g.
699
- building a new BioSimSpace binary, updating the website, etc. To this end, we
700
- have provided a git hook that will append ``ci skip `` if the commit only
701
- modifies files in a blacklist that is specified in the file ``.ciignore ``
702
- (analogous to the ``.gitignore `` used to ignore untracked files). To enable
703
- the hook, simply copy it into the ``.git/hooks `` directory:
704
-
705
- .. code-block :: bash
706
-
707
- cp git_hooks/commit-msg .git/hooks
708
-
709
- Any additional files or paths that shouldn't trigger a re-build can be added
710
- to the ``.ciignore `` file.
711
-
712
- Next, push your changes to the remote server, e.g.
713
-
714
- .. code-block :: bash
715
-
716
- # Push to the feature branch on the main BioSimSpace repo, if you have access.
717
- git push origin feature
718
-
719
- # Push to the feature branch your own fork.
720
- git push fork feature
721
-
722
- When the feature is complete, create a *pull request * on GitHub so that the
723
- changes can be merged back into the development branch. For information, see
724
- the documentation `here <https://help.github.com/articles/about-pull-requests >`__.
0 commit comments