This will not be a short answer, so let me better first address the shorter issues.

A possible IDE to use for debugging purposes is `eclipse`

, install also pydev as plugin inside. This worked for me a long time. Some post that shows how to combine sage devel in eclipse+pydev is here:

my sage+eclipse+pydev solution (posted as error)

For short: The IDE **must** (or should) be started from the terminal, e.g. `eclipse &`

, **after** setting via

```
`sage -sh`
```

in the "sage shell" all system variables to be used. Inside eclipse, each module should have the usual `from sage.all import *`

, and if sage is configured as python interpreter (instead `python2.7`

), than there may be also some change needed... (The problem in the above post.) Important note: There is *no preparsing*, so things may become delicate. E.g. the `p = 2^8-1`

is rejected in `eclipse`

, instead, the code should be written as `p = 2**8-1`

, which is accepted in both worlds, sage and python2. Also, the "intervall" `[1..10]`

does exist only after preparsing, and it is a list of `ZZ`

-numbers, not a list of python `int`

egers. A simple replacement of `[1..10]`

by the "naive" `range(1,11)`

may thus fail for "unexpected reasons" in eclipse, although sage may load the code without errors... So this was one of the short issues.

A deviation / derivative of eclipse is LiClipse, not free... Never tried it, but one may expect also support after paying for it!

An other IDE for python can be used, `pycharm`

. The same discussion as in the case of `eclipse`

applies for it. Here is my parallel answer for the `pycharm`

world:

38750/how-i-use-sage-with-pycharm-in-ubuntu/

the sage (iron python) interpreter is my best friend. Just copy+paste (using `%cpaste`

) short pieces of code, or load bigger chunks. (Or install even bigger ones as packages.) There is an automatic TAB-completion for methods, which makes it productive in a different way, compared with a good editor as `emacs`

, my choice. (I could not make `emacs`

consume the code. Yet.)

And the rest of the post goes to `pytest`

.

The following strategy worked for me, some pytest test sage code could be digested as follows.

First of all, i installed `pytest`

for the `python2.7`

interpreter. (Default is to use it for python3.) On this manjaro machine i installed the package `python2-pytest`

in version `3,3,2-1`

from the `community`

manjaro repository. (This is thus an official manjaro package, and sage is also an official one in this distro! I'll stay with it...)

Then in a terminal: `sage -sh`

- same game as for eclipse and pycharm, this sets all related `SAGE`

paths and libraries. (Environment variables.) The prompter changes correspondingly.

With the new prompter i started:

```
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
```

i.e. the command `python2.7 -m pytest pytest_sagetest.py`

from the folder `asksage`

where the file `pytest_sagetest.py`

with the following content lives in:

```
# content of pytest_sagetest.py
from sage.all import *
def test_HasseBoundTest():
"""Test the computations of the order of an elliptic curve
by testing if it stays in the Hasse interval.
"""
p = 127
F = GF(p)
for a in GF(p):
try:
E = EllipticCurve( F, [a,0] )
except Exception:
continue
ord = E.order()
# lower bound check
assert( ord >= p + 1 - 2*sqrt(p) )
assert( ord <= p + 1 + 2*sqrt(p) )
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
assert( max(orders) == floor(p + 1 + 2*sqrt(p)) )
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
```

It was an intention to produce "errors". (Of course, some not so intentioned errors are also present... Since we want more errors, they remained in the landscape.) Then the `pytest`

digestive delivers the following information:

```
(sage-sh) dan@k7:asksage$ python2.7 -m pytest pytest_sagetest.py
================================ test session starts ================================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 3 items
pytest_sagetest.py .FF [100%]
===================================== FAILURES ======================================
_____________________________ test_LowerHasseBoundTaken _____________________________
def test_LowerHasseBoundTaken():
p = next_prime(100)
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
> assert( min(orders) == ceil(p + 1 - 2*sqrt(p)) )
E assert 83 == 82
E + where 83 = min([102, 105, 92, 114, 112, 87, ...])
E + and 82 = ceil(((101 + 1) - (2 * sqrt(101))))
E + where sqrt(101) = sqrt(101)
pytest_sagetest.py:37: AssertionError
________________________________ test_AllOrdersTaken ________________________________
def test_AllOrdersTaken():
p = 71
F = GF(p)
orders = []
for a in F:
for b in F:
try:
E = EllipticCurve( F, [a,b] )
except Exception:
pass # discriminant is zero...
ord = E.order()
if ord not in orders:
orders.append( ord )
# lower bound check
orders.sort()
> assert( orders == range( ceil (p + 1 - 2*sqrt(p)) ,
floor(p + 1 + 2*sqrt(p)) + 1 ) )
E assert [56, 57, 59, 60, 61, 62, ...] == [56, 57, 58, 59, 60, 61, ...]
E At index 2 diff: 59 != 58
E Right contains more items, first extra item: 85
E Use -v to get the full diff
pytest_sagetest.py:56: AssertionError
================================= warnings summary ==================================
pytest_sagetest.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
================== 2 failed, 1 passed, 1 warnings in 7.43 seconds ===================
(sage-sh) dan@k7:asksage$
```

(And here there is a lot of colourful highlight gone. Just start in a proper termina...)

Note: `pytest`

is rather a "unit test" tool, it may be used in a "test driven devel" process. Personally, for my research this is too much (i.e. life is too short). But this is of huge importance while for devel+maintain of the packages. Sage has also a proper mechanism for doing this. In fact, after installing `sage`

one has already the chance to test it against the unit test code sage comes with...

**LATER EDIT :: import issues**

Note that `pytest`

has a specific way to use a python path.

https://docs.pytest.org/en/latest/pythonpath.html

There is even a package `pytest-pythonpath`

that may make complicated things easier.

https://pypi.python.org/pypi/pytest-pythonpath

In our case, a simplistic situation as the following one could import a module (in the same directory).

Here is the situation:

```
[dan@k7 ~/asksage/asksage]$ ls tests
mycomputations.py test_sage.py
[dan@k7 ~/asksage/asksage]$ cat tests/mycomputations.py
# content of mycomputations.py
from sage.all import *
def PythonInteger(k):
return int(k)
def ZZInteger(k):
return ZZ(k)
[dan@k7 ~/asksage/asksage]$ cat tests/test_sage.py
# content of test_sage.py
from sage.all import *
import mycomputations
def test_type1():
a = mycomputations.PythonInteger(100)
assert type(a) == type(ZZ(0))
def test_type2():
a = mycomputations.ZZInteger(100)
assert type(a) == type(ZZ(0))
[dan@k7 ~/asksage/asksage]$
```

Then:

```
[dan@k7 ~/asksage/asksage]$ pytest2 tests
======================== test session starts =========================
platform linux2 -- Python 2.7.14, pytest-3.3.2, py-1.5.0, pluggy-0.6.0
rootdir: /home/dan/asksage/asksage, inifile:
collected 2 items
tests/test_sage.py F. [100%]
============================== FAILURES ==============================
_____________________________ test_type1 _____________________________
def test_type1():
a = mycomputations.PythonInteger(100)
> assert type(a) == type(ZZ(0))
E AssertionError: assert <type 'int'> == <type 'sage.rings.integer.Integer'>
E + where <type 'int'> = type(100)
E + and <type 'sage.rings.integer.Integer'> = type(0)
E + where 0 = ZZ(0)
tests/test_sage.py:7: AssertionError
========================== warnings summary ==========================
tests/test_sage.py::TestSuite
cannot collect test class 'TestSuite' because it has a __init__ constructor
-- Docs: http://doc.pytest.org/en/latest/warnings.html
=========== 1 failed, 1 passed, 1 warnings in 3.69 seconds ===========
[dan@k7 ~/asksage/asksage]$
```

More complicated unit test situations are covered by the pytest documentation / framework. If such issues remain, please consider using an IDE, eclipse and/or pycharm, both are comming with a *supported* unit test environment.

The post also mentions (asks for) debugging possibilities, same answer, eclipse+pydev and/or pycharm so far.

Personal note: People that have not used such IDEs (e.g. because having a pure mathematical formation and/or because using rather the notebook part of sage) will discover a new world with good productivity mechanisms.

What actual problem are you have? And what do you mean exactly by "work with sage"? If you mean run Sage's own test suite, it won't. Sage has its own test runner. But for testing a package that happens to use Sage as a library it should work, as long as it's pure Python code and not, say, a

`.sage`

module (for that to work we'd need a plugin for pytest).@Iguananaut I am talking about writing my own code in the Sage language. I currently write code and save it in

`.sage`

files. Perhaps there is another recommended way to write Sage code in a convenient way that I don't know of.