Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Improve error messaging in Q# test & application projects  #141

@vadym-kl

Description

@vadym-kl

What you would like the feature to accomplish.

Currently when a single test fails the error message is verbose, hard to read and exposes C# code generation internals.
See below for an example. Similar improvement would be nice to have in the code that is generated when creating Q# console application.

Additional context

Consider a test project with a single qsharp file with a single test that fails:

namespace qsharp_unit_test_example {
    
    open Microsoft.Quantum.Canon;
    open Microsoft.Quantum.Diagnostics;
    open Microsoft.Quantum.Intrinsic;

    @Test("QuantumSimulator")
    operation AllocateQubit () : Unit {
        
        using (q = Qubit()) {
            X(q); // the new line we added to make test fail
            Assert([PauliZ], [q], Zero, "Newly allocated qubit must be in |0> state."); //test fails here
        }
        
        Message("Test passed.");
    }
}

Then run dotnet test for the project and observe the following output:

[xUnit.net 00:00:01.12]     qsharp_unit_test_example.AllocateQubit+QuantumSimulator.AllocateQubit [FAIL]
  X qsharp_unit_test_example.AllocateQubit+QuantumSimulator.AllocateQubit [52ms]
  Error Message:
   System.AggregateException : One or more errors occurred. (Newly allocated qubit must be in |0> state.
        Expected:       0
        Actual: 1)
---- Microsoft.Quantum.Simulation.Core.ExecutionFailException : Newly allocated qubit must be in |0> state.
        Expected:       0
        Actual: 1
  Stack Trace:
     at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at qsharp_unit_test_example.AllocateQubit.QuantumSimulator.AllocateQubit() in D:\repos\qsharp-unit-test-example\Tests.qs:line 16
----- Inner Stack Trace -----
   at Microsoft.Quantum.Simulation.Simulators.QuantumSimulator.QSimAssert.<get_Body>b__6_0(ValueTuple`4 _args)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)
   at qsharp_unit_test_example.AllocateQubit.<get_Body>b__27_0(QVoid __in__) in D:\repos\qsharp-unit-test-example\Tests.qs:line 13
--- End of stack trace from previous location where exception was thrown ---
   at qsharp_unit_test_example.AllocateQubit.<get_Body>b__27_0(QVoid __in__) in D:\repos\qsharp-unit-test-example\Tests.qs:line 14
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply[GenO](Object args)
   at Microsoft.Quantum.Simulation.Common.SimulatorBase.Execute[T,I,O](I args)
   at Microsoft.Quantum.Simulation.Common.SimulatorBase.<>c__DisplayClass39_0`3.<Run>b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) 
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state) 
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
  Standard Output Messages:
 Unhandled exception. Microsoft.Quantum.Simulation.Core.ExecutionFailException: Newly allocated qubit must be in |0> state.
        Expected:       0
        Actual: 1
  ---> Microsoft.Quantum.Intrinsic.Assert on :line 13
    at qsharp_unit_test_example.AllocateQubit on D:\repos\qsharp-unit-test-example\Tests.qs:line 9

Potential solution

It would be nice if currently generated C# code in Tests.g.cs

public void AllocateQubit()
#line 9 "D:/repos/qsharp-unit-test-example/Tests.qs"
{
    var sim = new Microsoft.Quantum.Simulation.Simulators.QuantumSimulator();
    if (sim is Microsoft.Quantum.Simulation.Common.SimulatorBase baseSim && this.Output != null)
    {
        baseSim.OnLog += this.Output.WriteLine;
    }

    sim.Run<AllocateQubit, QVoid, QVoid>(QVoid.Instance).Wait();
    if (sim is IDisposable disposeSim)
    {
        disposeSim.Dispose();
    }
}

looked more like:

public void AllocateQubit()
#line 9 "D:/repos/qsharp-unit-test-example/Tests.qs"
{
    var sim = new Microsoft.Quantum.Simulation.Simulators.QuantumSimulator();
    if (sim is Microsoft.Quantum.Simulation.Common.SimulatorBase baseSim && this.Output != null)
    {
        baseSim.OnLog += this.Output.WriteLine;
    }
    try
    {
        sim.Execute<AllocateQubit, QVoid, QVoid>(QVoid.Instance);
    }
    catch(Exception e) 
    {
#line 9 "D:/repos/qsharp-unit-test-example/Tests.qs"        
        Xunit.Assert.True(false,"Q# Test failed. For details see the Standard output below.");
    }
    finally
    {
        if (sim is IDisposable disposeSim)
        {
            disposeSim.Dispose();
        }
    }
}

which leads to the following output upon test failure:

[xUnit.net 00:00:01.10]     qsharp_unit_test_example2.AllocateQubit+QuantumSimulator.AllocateQubit [FAIL]

  X qsharp_unit_test_example2.AllocateQubit+QuantumSimulator.AllocateQubit [51ms]
  Error Message:
   Q# Test failed. For details see the Standard Output Messages below.
Expected: True
Actual:   False
  Stack Trace:
     at qsharp_unit_test_example2.AllocateQubit.QuantumSimulator.AllocateQubit() in D:\repos\qsharp-unit-test-example\Tests.qs:line 9
  Standard Output Messages:
 Unhandled exception. Microsoft.Quantum.Simulation.Core.ExecutionFailException: Newly allocated qubit must be in |0> state.
        Expected:       0
        Actual: 1
  ---> Microsoft.Quantum.Intrinsic.Assert on :line 13
    at qsharp_unit_test_example.AllocateQubit on D:\repos\qsharp-unit-test-example\Tests.qs:line 9

Also note that with current code QuantumSimulator is not disposed in case exception happens.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions