Sr. Content Developer at Microsoft, working remotely in PA, TechBash conference organizer, former Microsoft MVP, Husband, Dad and Geek.
141537 stories
·
32 followers

How Microsoft 365 Copilot and agents help tackle the infinite workday

1 Share

AI presents both a once-in-a-generation opportunity and a challenge to help every employee conquer the infinite workday.

The post How Microsoft 365 Copilot and agents help tackle the infinite workday appeared first on Microsoft 365 Blog.

Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

ESLint v9.30.0 released

1 Share

Highlights

basePath property in config objects

Config objects can now include the new basePath property to specify the path to a subdirectory to which the config object should apply to. If a config object has a basePath property, patterns specified in files and ignores are evaluated relative to the subdirectory represented by basePath. This makes it easier to write config objects that target a particular directory inside your project.

// eslint.config.js
import { defineConfig } from "eslint/config";
import js from "@eslint/js";

export default defineConfig([
    {
        basePath: "packages/hello-base-path",
        plugins: { js },
        extends: ["js/recommended"],
        ignores: ["coverage/**", "dist/**"],
    },
]);

You can read more about base paths in config objects in the documentation.

Stable feature flag v10_config_lookup_from_file

With the addition of the basePath property in config objects, the experimental configuration file resolution introduced in ESLint v9.12.0 has been finalized. It will become the default behavior in the next major release of ESLint. Accordingly, the feature flag unstable_config_lookup_from_file has been renamed to v10_config_lookup_from_file. The old flag name still works, so if you are already using unstable_config_lookup_from_file in your setup, you don’t need to take any action.

New allowSeparateTypeImports option in no-duplicate-imports

With the new option allowSeparateTypeImports, the no-duplicate-imports rule can now be configured to treat import and import type as separate usages, even if they specify the same module.

/*eslint no-duplicate-imports: ["error", { "allowSeparateTypeImports": false }]*/

import { someValue } from 'module';
import type { SomeType } from 'module';

Other notable changes

  • The SourceCode method getIndexFromLoc now throws an error if the argument specifies a negative value for the column property.

Features

Bug Fixes

Documentation

Chores

  • 2b6491c chore: upgrade to @eslint/js@9.30.0 (#19889) (Francesco Trotta)
  • 5a5d526 chore: package.json update for @eslint/js release (Jenkins)
  • eaf8a41 chore: Correct typos in linter tests (#19878) (kilavvy)
Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Let's build something phoenix.new (Friends)

1 Share

Our old friend Chris McCord, creator of Elixir’s Phoenix framework, tells us all about his new remote AI runtime for building Phoenix apps. Along the way, we vibe code one of my silly app ideas, calculate all the money we’re going to spend on these tools, and get existential about what it all means.

Join the discussion

Changelog++ members save 4 minutes on this episode because they made the ads disappear. Join today!

Sponsors:

  • RetoolAssemble your elite AI team, arm them with powerful custom tools, and watch them make your to-do list disappear. Start for free or book a demo at retool.com/agents
  • Depot10x faster builds? Yes please. Build faster. Waste less time. Accelerate Docker image builds, and GitHub Actions workflows. Easily integrate with your existing CI provider and dev workflows to save hours of build time.

Featuring:

Show Notes:

Something missing or broken? PRs welcome!





Download audio: https://op3.dev/e/https://cdn.changelog.com/uploads/friends/99/changelog--friends-99.mp3
Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

PPP 466 | 12 Tools Every Leader Needs to Navigate Difficult Bosses, with Josefine Campbell

1 Share

Summary

In this episode, Andy welcomes back leadership coach Josefine Campbell to discuss her newest book, 12 Tools for Managing a Selfish Leader. If you’ve ever had a boss who seemed unpredictable, emotionally draining, or even manipulative, this conversation offers tools and insights that can help.

Josefine shares the inspiration behind the book, which is based on the story of a coaching client who successfully navigated a toxic leadership environment. You’ll learn how to identify the early signals of stress in yourself and your team, apply tools like the Stress Staircase and the Three Relationship Circles, and recognize behaviors like “praise with a twist.” Most importantly, Josefine emphasizes the critical turning point: recognizing that while you can’t change a selfish leader, you can change how you manage yourself to better navigate the relationship.

If you’re looking for insights on how to manage up, preserve your well-being, and lead yourself through challenging leadership dynamics, this episode is for you!

Sound Bites

  • “To qualify as a selfish leader, the way I use the term: it's someone who puts their own interests before the interests of the common good of the company, of the team, and of the people.”
  • “Your breath is the only vital response you can control. It's your way back to calm in the moment.”
  • “Over-responsibility is a shadow trait of high achievers. When you are highly responsible, it has a dark side. It makes it difficult for you to let go.”
  • “I cannot change him. I can somehow manage him, but it is about how I manage myself to manage him.”
  • “The turning point comes when you stop trying to change them and start managing yourself.”

Chapters

  • 00:00 Introduction
  • 02:07 Start of Interview
  • 02:20 Why This Book? What Sparked the Idea?
  • 06:00 What Is—and Isn’t—a Selfish Leader?
  • 08:40 Subtle Early Warning Signs of Stress
  • 10:09 The Stress Staircase: What It Is and How to Use It
  • 13:00 From a Hijacked Mental State to Being Ready
  • 16:49 Techniques: Rewriting History and Praise With a Twist
  • 23:35 Over-Responsibility and High Achievers
  • 26:20 The Three Relationship Circles
  • 29:04 Managing Yourself to Manage Them
  • 32:36 Stay or Go? Coaching Through That Crossroads
  • 35:01 End of Interview
  • 35:36 Andy Comments After the Interview
  • 39:03 Outtakes

Learn More

You can learn more about Josefine and her book at josefinecampbell.com/books.

For more learning on this topic, check out:

  • Episode 395, our first conversation with Josefine about leading through complexity.
  • Episode 317 with Mary Abbajay about managing up and succeeding with any boss.
  • Episode 422 with Bruce Tulgan on how to manage your boss.

Pass the PMP Exam This Year

If you or someone you know is thinking about getting PMP certified, we’ve put together a helpful guide called The 5 Best Resources to Help You Pass the PMP Exam on Your First Try. We’ve helped thousands of people earn their certification, and we’d love to help you too. It's totally free, and it's a great way to get a head start.

Just go to 5BestResources.PeopleAndProjectsPodcast.com to grab your copy. I’d love to help you get your PMP this year!

Thank you for joining me for this episode of The People and Projects Podcast!

Talent Triangle: Power Skills

Topics: Leadership, Project Management, Managing Up, Emotional Intelligence, Coaching, Stress Management, Toxic Leadership, Conflict Navigation, Workplace Psychology, Self-Leadership, Empathy, Team Dynamics

The following music was used for this episode:

Music: Summer Awakening by Frank Schroeter
License (CC BY 4.0): https://filmmusic.io/standard-license

Music: Tuesday by Sascha Ende
License (CC BY 4.0): https://filmmusic.io/standard-license





Download audio: https://traffic.libsyn.com/secure/peopleandprojectspodcast/466-JosefineCampbell.mp3?dest-id=107017
Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Testcontainers Best Practices for .NET Integration Testing

1 Share

BREAKING: PagerDuty Actually Fixed Incident Management
Remember when PagerDuty was just for alerting? Plot twist: They've quietly bundled and enhanced complete incident management into ALL plans - including custom workflows, Slack-first everything, AI-powered summaries, and incident roles. Your incident management deserves better than browser tabs and hope. Check it out here.

Nick Chapsas' Dometrain is celebrating 2 years of teaching .NET developers, and they are offering their "From Zero to Hero: REST APIs in .NET" course for free. Until the end of June, use the link below, and the course is yours to keep for 1 month. Get it for free.

Integration tests with Testcontainers are powerful, but they can quickly become a maintenance nightmare if you don't follow the right patterns.

I've seen teams struggle with flaky tests, slow test suites, and configuration headaches that could have been avoided with better practices from the start.

Today, I'll show you the patterns that make Testcontainers tests reliable, fast, and easy to maintain.

How Testcontainers Changes Integration Testing

Traditional integration tests often rely on shared test databases or in-memory alternatives that don't match production behavior. You either deal with test pollution between runs or sacrifice realism for speed.

Testcontainers solves this by spinning up real Docker containers for your dependencies. Your tests run against actual PostgreSQL, Redis, or any other service you use in production. When tests complete, containers are destroyed, giving you a clean slate every time.

The magic happens through Docker's API. Testcontainers manages the entire lifecycle: pulling images, starting containers, waiting for readiness, and cleanup. Your test code just needs to know how to connect.

Prerequisites

First, make sure you have the necessary packages:

Install-Package Microsoft.AspNetCore.Mvc.Testing
Install-Package Testcontainers.PostgreSql
Install-Package Testcontainers.Redis

If you want to learn more about the basic setup, check out my article on integrating testing with Testcontainers.

Creating Test Containers

Here's how to set up your containers with proper configuration:

PostgreSqlContainer _postgresContainer = new PostgreSqlBuilder()
    .WithImage("postgres:17")
    .WithDatabase("devhabit")
    .WithUsername("postgres")
    .WithPassword("postgres")
    .Build();

RedisContainer _redisContainer = new RedisBuilder()
    .WithImage("redis:latest")
    .Build();

To start and stop containers cleanly across your test suite, implement IAsyncLifetime in your WebApplicationFactory:

public sealed class IntegrationTestWebAppFactory : WebApplicationFactory<Program>, IAsyncLifetime
{
    public async Task InitializeAsync()
    {
        await _postgresContainer.StartAsync();
        await _redisContainer.StartAsync();
        // Start other dependencies here
    }

    public async Task DisposeAsync()
    {
        await _postgresContainer.StopAsync();
        await _redisContainer.StopAsync();
    }
}

This ensures containers are ready before tests run and cleaned up afterward. This means no leftover Docker state or race conditions.

A tip: pin your image versions (like postgres:17) to avoid surprises from upstream changes

I learned this the hard way when a minor version update caused my tests to fail unexpectedly.

Pass Configuration to Your App

The biggest mistake I see is hardcoding connection strings. Testcontainers assigns dynamic ports. Don't hardcode anything.

Instead, inject values via WebApplicationFactory.ConfigureWebHost:

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
    builder.UseSetting("ConnectionStrings:Database", _postgresContainer.GetConnectionString());
    builder.UseSetting("ConnectionStrings:Redis", _redisContainer.GetConnectionString());
}

The key is to use the UseSetting method to pass connection strings dynamically. It also avoids any race conditions or conflicts with other tests that might run in parallel.

This ensures your tests always connect to the right ports, regardless of what Docker assigns.

There's no need to remove services from the service collection or manually configure them (contrary to what you might find online). Just set the connection strings, and your application will use them automatically.

Share Expensive Setup with xUnit Collection Fixtures

What's a test fixture? A fixture is a shared context for your tests, allowing you to set up expensive resources like databases or message brokers once and reuse them across multiple tests.

This is where most teams get tripped up. The choice between class and collection fixtures affects both test performance and isolation.

Class Fixture - One container per test class:

Use class fixtures when tests modify global state or when debugging test interactions becomes difficult.

public class AddItemToCartTests : IClassFixture<DevHabitWebAppFactory>
{
    private readonly DevHabitWebAppFactory _factory;

    public AddItemToCartTests(DevHabitWebAppFactory factory)
    {
        _factory = factory;
    }

    [Fact]
    public async Task Should_ReturnFailure_WhenNotEnoughQuantity() { ... }
}

Collection Fixture - One container shared across multiple test classes:

Use collection fixtures when your tests don't modify shared state or when you can reliably clean up between tests.

[CollectionDefinition(nameof(IntegrationTestCollection))]
public sealed class IntegrationTestCollection : ICollectionFixture<DevHabitWebAppFactory>
{
}

Then apply it to your test classes:

[Collection(nameof(IntegrationTestCollection))]
public class AddItemToCartTests : IntegrationTestFixture
{
    public AddItemToCartTests(DevHabitWebAppFactory factory) : base(factory) { }

    [Fact]
    public async Task Should_ReturnFailure_WhenNotEnoughQuantity()
    {
        Guid customerId = await Sender.CreateCustomerAsync(Guid.NewGuid());
        var command = new AddItemToCartCommand(customerId, ticketTypeId, Quantity + 1);

        Result result = await Sender.Send(command);

        result.Error.Should().Be(TicketTypeErrors.NotEnoughQuantity(Quantity));
    }
}

When to use which:

  • Class fixtures when you need full isolation between test classes (slower but safer)
  • Collection fixtures when test classes don't interfere with each other (faster but requires discipline)

With collection fixtures, you have to take care of cleaning up any state that might persist between tests. This could include resetting databases, clearing caches, or removing test data. If you don't do this, you risk tests affecting each other, leading to flaky results.

Utility Methods for Auth and Cleanup

Your fixture can expose helpers to simplify test writing:

public async Task<HttpClient> CreateAuthenticatedClientAsync() { ... }

protected async Task CleanupDatabaseAsync() { ... }

These methods can handle authentication setup and database cleanup, so you don't have to repeat boilerplate code in every test. This lets your test code focus on assertions, not setup.

Writing Maintainable Integration Tests

With the infrastructure properly configured, your actual tests should focus on business logic:

[Fact]
public async Task Should_ReturnFailure_WhenNotEnoughQuantity()
{
    //Arrange
    Guid customerId = await Sender.CreateCustomerAsync(Guid.NewGuid());
    var eventId = Guid.NewGuid();
    var ticketTypeId = Guid.NewGuid();

    await Sender.CreateEventWithTicketTypeAsync(eventId, ticketTypeId, Quantity);

    var command = new AddItemToCartCommand(customerId, ticketTypeId, Quantity + 1);

    //Act
    Result result = await Sender.Send(command);

    //Assert
    result.Error.Should().Be(TicketTypeErrors.NotEnoughQuantity(Quantity));
}

Notice how the tests focus on business rules rather than infrastructure concerns. The container complexity is hidden behind well-designed base classes and helper methods. You're not mocking Postgres or Redis, you're testing real behavior.

Conclusion

Testcontainers transforms integration testing by giving you the confidence that comes from testing against real dependencies. No more wondering if your in-memory database behavior matches production, or dealing with shared test environments that break when someone else runs their tests.

Start simple: pick one integration test that currently uses mocks or in-memory databases, and convert it to use Testcontainers. You'll immediately notice the difference in confidence when that test passes. Then gradually expand to cover your critical business flows.

If you want to learn how to structure your applications for testability from day one, my Pragmatic Clean Architecture course covers integration testing with Testcontainers alongside domain modeling, API design, and the architectural decisions that make applications maintainable over time.

That's all for today.

See you next week.




Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete

Daily Reading List – June 27, 2025 (#577)

1 Share

It’s the end of a busy week. I’m looking forward to a hopefully-quiet weekend with the family and a few good books. Take a breather too!

[article] How much does AI impact development speed? Good look at some new research into how much AI impacts developers and their pace. Interesting that seniority and prior usage didn’t change the outcome.

[blog] Veo 3: A Detailed Prompting Guide. This is absolutely fantastic. Get all the right phrases and jargon to use when prompting a text-to-video model like Veo 3. Gold!

[blog] Gemini CLI: Technical Assessment Report – AI Hacker Lab Technical Analysis. Wow, what a thorough analysis. We’re only 3 days into this product, but we’ve already shipped a few updates, and somehow became the most starred agentic CLI on GitHub.

[article] Walmart cracks enterprise AI at scale: Thousands of use cases, one framework. I liked some of the insights here, including an evolution of success metrics from funnels and conversion, to actual goal completion.

[blog] Coding agents have turned a corner. It’s fine when goofballs like me use these AI tools and offer guidance, but I really value the advice from capital-E Engineers like Brian. Here, he offers his direction on how to work with coding agents.

[blog] First steps with Gemini Code Assist agent mode. Excellent post that shows the workflow and tooling for using agents within your VS Code editor.

[blog] The rise of “context engineering.” The idea here is making sure the LLM has the right information and tools it needs to accomplish its task. It’s a system approach, versus thinking in prompts alone.

[blog] Introducing BigQuery ObjectRef: Supercharge your multimodal data and AI processing. This seems super cool and useful. Reference a binary object from within your structured tables and do single queries that can factor it all in.

[blog] The Google for Startups Gemini kit is here. Startups seem to gravitate towards Google, and we’re making it even better for them with this offering.

Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:



Read the whole story
alvinashcraft
3 hours ago
reply
Pennsylvania, USA
Share this story
Delete
Next Page of Stories