<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Api\Data\ProductInterfaceFactory;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Type;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Framework\Api\DataObjectHelper;
use Magento\TestFramework\Helper\Bootstrap;

$objectManager = Bootstrap::getObjectManager();
/** @var ProductInterfaceFactory $productFactory */
$productFactory = $objectManager->get(ProductInterfaceFactory::class);
/** @var DataObjectHelper $dataObjectHelper */
$dataObjectHelper = Bootstrap::getObjectManager()->get(DataObjectHelper::class);
/** @var ProductRepositoryInterface $productRepository */
$productRepository = $objectManager->get(ProductRepositoryInterface::class);

$product = $productFactory->create();
$productData = [
    ProductInterface::TYPE_ID => Type::TYPE_VIRTUAL,
    ProductInterface::ATTRIBUTE_SET_ID => 4,
    ProductInterface::SKU => 'virtual_product',
    ProductInterface::NAME => 'Virtual Product',
    ProductInterface::PRICE => 10,
    ProductInterface::VISIBILITY => Visibility::VISIBILITY_BOTH,
    ProductInterface::STATUS => Status::STATUS_ENABLED,
];
$dataObjectHelper->populateWithArray($product, $productData, ProductInterface::class);
/** Out of interface */
$product
    ->setWebsiteIds([1])
    ->setStockData([
        'qty' => 85.5,
        'is_in_stock' => true,
        'manage_stock' => true,
        'is_qty_decimal' => true
    ]);
$productRepository->save($product);
