- OS: XXX (Windows, macOS, latest Ubuntu LTS)
- Shell: XXX (Command Prompt, PowerShell, bash, fish)
- Python
- Distribution: XXX (CPython, miniconda)
- Version: XXX (2.7, latest 3.x)
- VS Code: XXX (Insiders)
ALWAYS:
- Check the
Outputwindow underPythonfor logged errors - Have
Developer Toolsopen to detect any errors - Consider running the tests in a multi-folder workspace
- Focus on in-development features (i.e. experimental debugger and language server)
Scenarios
- Interpreter is shown in the status bar
- An interpreter can be manually specified using the
Select Interpretercommand - Detected system-installed interpreters
- Detected an Anaconda installation
- (Linux/macOS) Detected all interpreters installed w/ pyenv detected
-
"python.pythonPath"triggers an update in the status bar -
Run Python File in Terminal -
Run Selection/Line in Python Terminal- Right-click
- Command
-
Shift+Enter
Sample file:
import requests
request = requests.get("https://drive.google.com/uc?export=download&id=1_9On2-nsBQIw3JiY43sWbrF8EjrqrR4U")
with open("survey2017.zip", "wb") as file:
file.write(request.content)
import zipfile
with zipfile.ZipFile('survey2017.zip') as zip:
zip.extractall('survey2017')
import shutil, os
shutil.move('survey2017/survey_results_public.csv','survey2017.csv')
shutil.rmtree('survey2017')
os.remove('survey2017.zip')- Shift+Enter to send selected code in sample file to terminal works
ALWAYS:
-
Use the latest version of Anaconda
-
Realize that
condais slow -
Create an environment with a space in their path somewhere as well as upper and lowercase characters
-
Make sure that you do not have
python.pythonPathspecified in yoursettings.jsonwhen testing automatic detection -
Do note that the
Select Interpreterdrop-down window scrolls -
Detected a single virtual environment at the top-level of the workspace folder on Mac when when
pythoncommand points to default Mac Python installation orpythoncommand fails in the terminal.- Appropriate suffix label specified in status bar (e.g.
(venv))
- Appropriate suffix label specified in status bar (e.g.
-
Detected a single virtual environment at the top-level of the workspace folder on Windows when
pythonfails in the terminal.- Appropriate suffix label specified in status bar (e.g.
(venv))
- Appropriate suffix label specified in status bar (e.g.
-
Detected a single virtual environment at the top-level of the workspace folder
- Appropriate suffix label specified in status bar (e.g.
(venv)) -
Create Terminalworks- Steals focus
-
"python.terminal.activateEnvironment": falsedeactivates automatically running the activation script in the terminal
- After the language server downloads it is able to complete its analysis of the environment w/o requiring a restart
- Appropriate suffix label specified in status bar (e.g.
-
Detect multiple virtual environments contained in the directory specified in
"python.venvPath" -
Detected all conda environments created with an interpreter
- Appropriate suffix label specified in status bar (e.g.
(condaenv)) - Prompted to install Pylint
- Asked whether to install using conda or pip
- Installs into environment
-
Create Terminalworks-
"python.terminal.activateEnvironment": falsedeactivates automatically running the activation script in the terminal
-
- After the language server downloads it is able to complete its analysis of the environment w/o requiring a restart
- Appropriate suffix label specified in status bar (e.g.
-
(Linux/macOS until
-mis supported) Detected the virtual environment created by pipenv- Appropriate suffix label specified in status bar (e.g.
(pipenv)) - Prompt to install Pylint uses
pipenv install --dev -
Create Terminalworks-
"python.terminal.activateEnvironment": falsedeactivates automatically running the activation script in the terminal
-
- After the language server downloads it is able to complete its analysis of the environment w/o requiring a restart
- Appropriate suffix label specified in status bar (e.g.
-
(Linux/macOS) Virtual environments created under
{workspaceFolder}/.direnv/python-{python_version}are detected (for direnv and itslayout python3support)- Appropriate suffix label specified in status bar (e.g.
(venv))
- Appropriate suffix label specified in status bar (e.g.
Sample files:
# example.py
import os
print('Hello,', os.environ.get('WHO'), '!')# .env
WHO=world
PYTHONPATH=some/path/somewhere
SPAM='hello ${WHO}'
ALWAYS:
-
Make sure to use
Reload Windowbetween tests to reset your environment -
Note that environment files only apply under the debugger and Jedi
-
Environment variables in a
.envfile are exposed when running under the debugger -
"python.envFile"allows for specifying an environment file manually (e.g. Jedi picks upPYTHONPATHchanges) -
envFilein alaunch.jsonconfiguration works -
simple variable substitution works
-
pythonPathsetting in yourlaunch.jsonoverrides yourpython.pythonPathdefault setting
ALWAYS:
- Check under the
Problemstab to see e.g. if a linter is raising errors
- LS is downloaded using HTTP (no SSL) when the "http.proxyStrictSSL" setting is false
- Installing
requestsin virtual environment is detected- Import of
requestswithout package installed is flagged as unresolved - Create a virtual environment
- Install
requestsinto the virtual environment
- Import of
[Prompting to install Pylint is covered under Environments above]
For testing the disablement of the default linting rules for Pylint:
# pylintrc
[MESSAGES CONTROL]
enable=bad-names# example.py
foo = 42 # Marked as a blacklisted name.- Installation via the prompt installs Pylint as appropriate
- Uses
--userfor system-install of Python - Installs into a virtual environment environment directly
- Uses
- Pylint works
-
"python.linting.pylintUseMinimalCheckers": falseturns off the default rules w/ nopylintrcfile present - The existence of a
pylintrcfile turns off the default rules
Note:
-
You can use the
Run Lintingcommand to run a newly installed linter -
When the extension installs a new linter, it turns off all other linters
-
flake8 works
-
Select linterlists the linter and installs it if necessary
-
-
mypy works
-
Select linterlists the linter and installs it if necessary
-
-
pep8 works
-
Select linterlists the linter and installs it if necessary
-
-
prospector works
-
Select linterlists the linter and installs it if necessary
-
-
pydocstyle works
-
Select linterlists the linter and installs it if necessary
-
-
pylama works
-
Select linterlists the linter and installs it if necessary
-
-
3 or more linters work simultaneously (make sure you have turned on the linters in your
settings.json)-
Run Lintingruns all activated linters -
"python.linting.enabled": falsedisables all linters - The
Enable Lintingcommand changes"python.linting.enabled"
-
-
"python.linting.lintOnSaveworks
Please also test for general accuracy on the most "interesting" code you can find.
-
"python.autoComplete.extraPaths"works -
"python.autocomplete.addBrackets": truecauses auto-completion of functions to append() - Auto-completions works
Sample file:
# There should be _some_ change after running `Format Document`.
import os,sys;
def foo():pass- Prompted to install a formatter if none installed and
Format Documentis run- Installing
autopep8works - Installing
blackworks - Installing
yapfworks
- Installing
- Formatters work with default settings (i.e.
"python.formatting.provider"is specified but not matching*Pathor*Argssettings)- autopep8
- black
- yapf
- Formatters work when appropriate
*Pathand*Argssettings are specified (use absolute paths; use~if possible)- autopep8
- black
- yapf
-
"editor.formatOnType": trueworks and has expected results
-
Extract Variableworks- You are prompted to install
ropeif it is not already available
- You are prompted to install
-
Extract methodworks- You are prompted to install
ropeif it is not already available
- You are prompted to install
-
Sort Importsworks
- Configurations work (see
package.jsonand the"configurationSnippets"section for all of the possible configurations) - Running code from start to finish w/ no special debugging options (e.g. no breakpoints)
- Breakpoint-like things
- Breakpoint
- Set
- Hit
- Conditional breakpoint
- Expression
- Set
- Hit
- Hit count
- Set
- Hit
- Expression
- Logpoint
- Set
- Hit
- Breakpoint
- Stepping
- Over
- Into
- Out
- Can inspect variables
- Through hovering over variable in code
-
Variablessection of debugger sidebar
- Remote debugging works
- ... over SSH
- ... on other branches
- App Engine
import unittest
MODULE_SETUP = False
def setUpModule():
global MODULE_SETUP
MODULE_SETUP = True
class PassingSetupTests(unittest.TestCase):
CLASS_SETUP = False
METHOD_SETUP = False
@classmethod
def setUpClass(cls):
cls.CLASS_SETUP = True
def setUp(self):
self.METHOD_SETUP = True
def test_setup(self):
self.assertTrue(MODULE_SETUP)
self.assertTrue(self.CLASS_SETUP)
self.assertTrue(self.METHOD_SETUP)
class PassingTests(unittest.TestCase):
def test_passing(self):
self.assertEqual(42, 42)
def test_passing_still(self):
self.assertEqual("silly walk", "silly walk")
class FailingTests(unittest.TestCase):
def test_failure(self):
self.assertEqual(42, -13)
def test_failure_still(self):
self.assertEqual("I'm right!", "no, I am!")-
Run All Unit Teststriggers the prompt to configure the test runner - Tests are discovered (as shown by code lenses on each test)
- Code lens for a class runs all tests for that class
- Code lens for a method runs just that test
-
Run Testworks -
Debug Testworks - Module/suite setup methods are also run (run the
test_setupmethod to verify)
-
- while debugging tests, an uncaught exception in a test does not cause ptvsd to raise SystemExit
def test_passing():
assert 42 == 42
def test_failure():
assert 42 == -13-
Run All Unit Teststriggers the prompt to configure the test runner-
pytestgets installed
-
- Tests are discovered (as shown by code lenses on each test)
-
Run Testworks -
Debug Testworks
-
- A
Diagnosticis shown in the problems pane for each failed/skipped test- The
Diagnostics are organized according to the file the test was executed from (not necessarily the file it was defined in) - The appropriate
DiagnosticRelatedInformationis shown for eachDiagnostic - The
DiagnosticRelatedInformationreflects the traceback for the test
- The
def test_passing():
assert 42 == 42
def test_failure():
assert 42 == -13-
Run All Unit Teststriggers the prompt to configure the test runner- Nose gets installed
- Tests are discovered (as shown by code lenses on each test)
-
Run Testworks -
Debug Testworks
-
- Code lenses appears
-
Run Testlens works (and status bar updates as appropriate) -
Debug Testlens works - Appropriate ✔/❌ shown for each test
-
- Status bar is functioning
- Appropriate test results displayed
-
Run All Unit Testsworks -
Discover Unit Testsworks (resets tests result display in status bar) -
Run Unit Test Method ...works -
View Unit Test Outputworks - After having at least one failure,
Run Failed Testsworks
-
Configure Unit Testsworks- quick pick for framework (and its settings)
- selected framework enabled in workspace settings
- framework's config added (and old config removed)
- other frameworks disabled in workspace settings
-
Configure Unit Testsdoes not close if it loses focus - Cancelling configuration does not leave incomplete settings
- The first
"request": "test"entry in launch.json is used for running unit tests
- Start and connect to local Jupyter server
- Open the file src/test/datascience/manualTestFiles/manualTestFile.py in VSCode
- At the top of the file it will list the things that you need installed in your Python environment
- On the first cell click
Run Below - Interactive Window should open, show connection information, and execute cells
- The first thing in the window should have a line like this:
Jupyter Server URI: http://localhost:[port number]/?token=[token value]
- Verify basic outputs
- Run all the cells in manualTestFile.py
- Check to make sure that no outputs have errors
- Verify that graphs and progress bars are shown
- Verify export / import
- With the results from
Start and connect to local serveropen click theExport as Jupyter Notebookbutton in the Interactive Window - Choose a file location and save the generated .ipynb file
- When the prompt comes up in the lower right choose to open the file in the browser
- The file should open in the web browser and contain the output from the Interactive Window
- In VSCode open up the exported .ipynb file in the editor, when the prompt for
Do you want to import the Jupyter Notebook into Python code?appears click import - The imported file should match the original python file
- With the results from
- Verify text entry
- In the Interactive Window type in some new code
print('testing')and submit it to the Interactive Windows - Verify the output from what you added
- In the Interactive Window type in some new code
- Verify dark and light main themes
- Repeat the
Start and connect to local serverandVerify basic outputssteps usingDefault Dark+andDefault Light+themes
- Repeat the
- Verify Variable Explorer
- After manualTestFile.py has been run drop down the Variables section at the top of the Interactive Window
- In the Variables list there should be an entry for all variables created. These variables might change as more is added to manualTestFile.py.
- Check that variables have expected values. They will be truncated for longer items
- Sort the list ascending and descending by Type. Also sort the list ascending and descending by Count. Values like (X, Y) use the first X value for Count sort ordering
- Check that list, Series, ndarray, and DataFrame types have a button to "Show variable in data viewer" on the right
- In the Interactive Window input box add a new variable. Verify that it is added into the Variable Explorer
- Verify Data Explorer
- From the listed types in the Variable explorer open up the Data Viewer by clicking the button or double clicking the row
- Inspect the data in the Data Viewer for the expected values
[ ] Verify Sorting and Filtering
- Open up the myDataFrame item
- Sort the name column ascending and descending
- Sort one of the numerical columns ascending and descending
- Click the Filter Rows button
- In the name filter box input 'a' to filter to just name with an a in them
- In one of the numerical columns input a number 1 - 9 to filter to just that column
- Open the myList variable in the explorer
- Make sure that you can scroll all the way to the end of the entries
- Connect to a
remoteserver- Open up a valid python command prompt that can run
jupyter notebook(a default Anaconda prompt works well) - Run
jupyter notebookto start up a local Jupyter server - In the command window that launched Jupyter look for the server / token name like so: http://localhost:8888/?token=bf9eae43641cd75015df9104f814b8763ef0e23ffc73720d
- Run the command
Python: Select Jupyter server URIthenType in the URI to connect to a running jupyter server - Input the server / token name here
- Now run the cells in the manualTestFile.py
- Verify that you see the server name in the initial connection message
- Verify the outputs of the cells
- Open up a valid python command prompt that can run
- Interactive Window commands
- Verify per-cell commands
- Expand and collapse the input area of a cell
- Use the
Xbutton to remove a cell - Use the
Goto Codebutton to jump to the part of the .py file that submitted the code
- Verify top menu commands
- Use
Xto delete all cells - Undo the delete action with
Undo - Redo the delete action with
Redo - In manualTestFile.py modify the trange command in the progress bar from 100 to 2000. Run the Cell. As the cell is running hit the
Interrupt iPython Kernelbutton - The progress bar should be interrupted and you should see a KeyboardInterrupt error message in the output
- Test the
Restart iPython kernelcommand. Kernel should be restarted and you should see a status output message for the kernel restart - Use the expand all input and collapse all input commands to collapse all cell inputs
- Use
- Verify per-cell commands
- Verify theming works
- Start Python Interactive window
- Add a cell with some comments
- Switch VS Code theme to something else
- Check that the cell you just added updates the comment color
- Switch back and forth between a 'light' and a 'dark' theme
- Check that the cell switches colors
- Check that the buttons on the top change to their appropriate 'light' or 'dark' versions
- Enable the 'ignoreVscodeTheme' setting
- Close the Python Interactive window and reopen it. The theme in just the 'Python Interactive' window should be light
- Switch to a dark theme. Make sure the interactive window remains in the light theme.
- Verify code lenses
- Check that
Run CellRun AboveandRun Belowall do the correct thing
- Check that
- Verify context menu navigation commands
- Check the
Run Current CellandRun Current Cell And Advancecontext menu commands - If run on the last cell of the file
Run Current Cell And Advanceshould create a new empty cell and advance to it
- Check the
- Verify command palette commands
- Close the Interactive Window then pick
Python: Show Interactive Window - Restart the kernel and pick
Python: Run Current File In Python Interactive Windowit should run the whole file again
- Close the Interactive Window then pick
- Verify shift-enter
- Move to the top cell in the .py file
- Shift-enter should run each cell and advance to the next
- Shift-enter on the final cell should create a new cell and move to it
- Verify file without cells
- Open the manualTestFileNoCells.py file
- Select a chunk of code, shift-enter should send it to the terminal
- Open VSCode settings, change
Send Selection To Interactive Windowto true - Select a chunk of code, shift-enter should send that selection to the Interactive Windows
- Move your cursor to a line, but don't select anything. Shift-enter should send that line to the Interactive Window
- Multiple installs
- Close and re-open VSCode to make sure that all jupyter servers are closed
- Also make sure you are set to locally launch Jupyter and not to connect to an existing URI
- In addition to your main testing environment install a new python or miniconda install (conda won't work as it has Jupyter by default)
- In VS code change the python interpreter to the new install
- Try
Run Cell - You should get a message that Jupyter was not found and that it is defaulting back to launch on the python instance that has Jupyter
- LiveShare Support
- Install the LiveShare VSCode Extension
- Open manualTestFile.py in VSCode
- Run the first cell in the file
- Switch to the
Live Sharetab in VS Code and start a session- Verify server start
- Jupyter server instance should appear in the live share tab
- Verify server start
- Open another window of VSCode
- Connect the second instance of VSCode as a Guest to the first Live Share session
- After the workspace opens, open the manualTestFile.py on the Guest instance
- On the Guest instance run a cell from the file, both via the codelens and via the command palette
Run Cellcommand- Verify results
- Output should show up on the Guest Interactive Window
- Same output should show up in the Host Interactive Window
- Verify results
- On the Host instance run a cell from the file, both via the codelens and via the command palette
- Verify results
- Output should show up on the Guest Interactive Window
- Same output should show up in the Host Interactive Window
- Verify results
- Directory change
- Verify directory change in export
- Follow the previous steps for export, but export the ipynb to a directory outside of the current workspace
- Open the file in the browser, you should get an initial cell added to change directory back to your workspace directory
- Verify directory change in import
- Follow the previous steps for import, but import an ipynb that is located outside of your current workspace
- Open the file in the editor. There should be python code at the start to change directory to the previous location of the .ipynb file
- Verify directory change in export
- Interactive Window input history history
- Start up an Interactive Window session
- Input several lines into the Interactive Window terminal
- Press up to verify that those previously entered lines show in the Interactive Window terminal history
- Extra themes
- Try several of the themes that come with VSCode that are not the default Dark+ and Light+